Commit 438e4af7 authored by hjk's avatar hjk

CppEditor: simplify CppQuickFixOperation interface

Change-Id: Ib3ed82c7f07f80027b18471ffb7b3055fa74eb52
Reviewed-by: default avatarErik Verbruggen <erik.verbruggen@digia.com>
parent 9f38f7bf
......@@ -112,10 +112,11 @@ public:
"Complete Switch Statement"));
}
virtual void performChanges(const CppRefactoringFilePtr &currentFile,
const CppRefactoringChanges &)
void perform()
{
CppRefactoringChanges refactoring(snapshot());
CppRefactoringFilePtr currentFile = refactoring.file(fileName());
ChangeSet changes;
int start = currentFile->endOf(compoundStatement->lbrace_token);
changes.insert(start, QLatin1String("\ncase ")
......@@ -130,8 +131,9 @@ public:
QStringList values;
};
static Enum *findEnum(const QList<LookupItem> &results,
const LookupContext &ctxt)
} // end of anonymous namespace
static Enum *findEnum(const QList<LookupItem> &results, const LookupContext &ctxt)
{
foreach (const LookupItem &result, results) {
const FullySpecifiedType fst = result.type();
......@@ -153,8 +155,7 @@ static Enum *findEnum(const QList<LookupItem> &results,
return 0;
}
static Enum *conditionEnum(const QSharedPointer<const CppEditor::Internal::CppQuickFixAssistInterface> &interface,
SwitchStatementAST *statement)
static Enum *conditionEnum(const CppQuickFixInterface &interface, SwitchStatementAST *statement)
{
Block *block = statement->symbol;
Scope *scope = interface->semanticInfo().doc->scopeAt(block->line(), block->column());
......@@ -167,15 +168,12 @@ static Enum *conditionEnum(const QSharedPointer<const CppEditor::Internal::CppQu
return findEnum(results, typeOfExpression.context());
}
} // end of anonymous namespace
QList<CppQuickFixOperation::Ptr> CompleteSwitchCaseStatement::match(
const QSharedPointer<const CppEditor::Internal::CppQuickFixAssistInterface> &interface)
void CompleteSwitchCaseStatement::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
{
const QList<AST *> &path = interface->path();
if (path.isEmpty())
return noResult(); // nothing to do
return;
// look for switch statement
for (int depth = path.size() - 1; depth >= 0; --depth) {
......@@ -183,10 +181,10 @@ QList<CppQuickFixOperation::Ptr> CompleteSwitchCaseStatement::match(
SwitchStatementAST *switchStatement = ast->asSwitchStatement();
if (switchStatement) {
if (!interface->isCursorOn(switchStatement->switch_token) || !switchStatement->statement)
return noResult();
return;
CompoundStatementAST *compoundStatement = switchStatement->statement->asCompoundStatement();
if (!compoundStatement) // we ignore pathologic case "switch (t) case A: ;"
return noResult();
return;
// look if the condition's type is an enum
if (Enum *e = conditionEnum(interface, switchStatement)) {
// check the possible enum values
......@@ -205,15 +203,12 @@ QList<CppQuickFixOperation::Ptr> CompleteSwitchCaseStatement::match(
// save the values that would be added
foreach (const QString &usedValue, usedValues)
values.removeAll(usedValue);
if (values.isEmpty())
return noResult();
else
return singleResult(new Operation(interface, depth, compoundStatement, values));
if (!values.isEmpty())
result.append(CppQuickFixOperation::Ptr(new Operation(interface, depth, compoundStatement, values)));
return;
}
return noResult();
return;
}
}
return noResult();
}
......@@ -32,8 +32,6 @@
#include "cppquickfix.h"
#include <CPlusPlusForwardDeclarations.h>
namespace CppEditor {
namespace Internal {
......@@ -43,8 +41,7 @@ namespace Internal {
class CompleteSwitchCaseStatement: public CppQuickFixFactory
{
public:
virtual QList<CppQuickFixOperation::Ptr> match(
const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface);
void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
};
} // namespace Internal
......
......@@ -991,21 +991,18 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targ
class ApplyDeclDefLinkOperation : public CppQuickFixOperation
{
public:
explicit ApplyDeclDefLinkOperation(
const QSharedPointer<const CppEditor::Internal::CppQuickFixAssistInterface> &interface,
explicit ApplyDeclDefLinkOperation(const CppQuickFixInterface &interface,
const QSharedPointer<FunctionDeclDefLink> &link)
: CppQuickFixOperation(interface, 10)
, m_link(link)
{}
virtual void perform()
void perform()
{
CPPEditorWidget *editor = assistInterface()->editor();
QSharedPointer<FunctionDeclDefLink> link = editor->declDefLink();
if (link != m_link)
return;
return editor->applyDeclDefLinkChanges(/*don't jump*/false);
if (link == m_link)
editor->applyDeclDefLinkChanges(/*don't jump*/false);
}
protected:
......@@ -1016,17 +1013,13 @@ private:
QSharedPointer<FunctionDeclDefLink> m_link;
};
QList<CppQuickFixOperation::Ptr> ApplyDeclDefLinkChanges::match(const QSharedPointer<const CppQuickFixAssistInterface> &interface)
void ApplyDeclDefLinkChanges::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
{
QList<CppQuickFixOperation::Ptr> results;
QSharedPointer<FunctionDeclDefLink> link = interface->editor()->declDefLink();
if (!link || !link->isMarkerVisible())
return results;
return;
QSharedPointer<ApplyDeclDefLinkOperation> op(new ApplyDeclDefLinkOperation(interface, link));
op->setDescription(FunctionDeclDefLink::tr("Apply Function Signature Changes"));
results += op;
return results;
result += op;
}
......@@ -127,8 +127,7 @@ private:
class ApplyDeclDefLinkChanges: public CppQuickFixFactory
{
public:
virtual QList<CppQuickFixOperation::Ptr>
match(const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface);
void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
};
} // namespace Internal
......
......@@ -86,9 +86,10 @@ public:
"Add %1 Declaration").arg(type));
}
void performChanges(const CppRefactoringFilePtr &,
const CppRefactoringChanges &refactoring)
void perform()
{
CppRefactoringChanges refactoring(snapshot());
InsertionPointLocator locator(refactoring);
const InsertionLocation loc = locator.methodDeclarationInClass(
m_targetFileName, m_targetSymbol, m_xsSpec);
......@@ -147,8 +148,7 @@ Class *isMemberFunction(const LookupContext &context, Function *function)
} // anonymous namespace
QList<CppQuickFixOperation::Ptr> DeclFromDef::match(
const QSharedPointer<const CppEditor::Internal::CppQuickFixAssistInterface> &interface)
void DeclFromDef::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
{
const QList<AST *> &path = interface->path();
CppRefactoringFilePtr file = interface->currentFile();
......@@ -161,24 +161,21 @@ QList<CppQuickFixOperation::Ptr> DeclFromDef::match(
if (DeclaratorIdAST *declId = node->asDeclaratorId()) {
if (file->isCursorOn(declId)) {
if (FunctionDefinitionAST *candidate = path.at(idx - 2)->asFunctionDefinition()) {
if (funDef) {
return noResult();
} else {
funDef = candidate;
break;
}
if (funDef)
return;
funDef = candidate;
break;
}
}
}
}
if (node->asClassSpecifier()) {
return noResult();
}
if (node->asClassSpecifier())
return;
}
if (!funDef || !funDef->symbol)
return noResult();
return;
Function *fun = funDef->symbol;
if (Class *matchingClass = isMemberFunction(interface->context(), fun)) {
......@@ -191,17 +188,15 @@ QList<CppQuickFixOperation::Ptr> DeclFromDef::match(
if (s->type().isEqualTo(fun->type())) {
// Declaration exists.
return noResult();
return;
}
}
QString fileName = QString::fromUtf8(matchingClass->fileName(),
matchingClass->fileNameLength());
const QString decl = InsertDeclOperation::generateDeclaration(fun);
return singleResult(new InsertDeclOperation(interface, fileName, matchingClass,
InsertionPointLocator::Public, decl));
result.append(TextEditor::QuickFixOperation::Ptr(new InsertDeclOperation(interface, fileName, matchingClass,
InsertionPointLocator::Public, decl)));
}
return noResult();
}
QString InsertDeclOperation::generateDeclaration(Function *function)
......@@ -220,9 +215,6 @@ QString InsertDeclOperation::generateDeclaration(Function *function)
namespace {
class InsertDefOperation: public CppQuickFixOperation
{
public:
......@@ -239,11 +231,10 @@ public:
.arg(dir.relativeFilePath(m_loc.fileName())));
}
void performChanges(const CppRefactoringFilePtr &,
const CppRefactoringChanges &refactoring)
void perform()
{
QTC_ASSERT(m_loc.isValid(), return);
CppRefactoringChanges refactoring(snapshot());
CppRefactoringFilePtr targetFile = refactoring.file(m_loc.fileName());
Overview oo;
......@@ -293,8 +284,7 @@ private:
} // anonymous namespace
QList<CppQuickFixOperation::Ptr> DefFromDecl::match(
const QSharedPointer<const CppEditor::Internal::CppQuickFixAssistInterface> &interface)
void DefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
{
const QList<AST *> &path = interface->path();
......@@ -310,22 +300,18 @@ QList<CppQuickFixOperation::Ptr> DefFromDecl::match(
&& decl->enclosingScope()->isClass()) {
CppRefactoringChanges refactoring(interface->snapshot());
InsertionPointLocator locator(refactoring);
QList<CppQuickFixOperation::Ptr> results;
foreach (const InsertionLocation &loc, locator.methodDefinition(decl)) {
if (loc.isValid())
results.append(CppQuickFixOperation::Ptr(new InsertDefOperation(interface, decl, loc)));
result.append(CppQuickFixOperation::Ptr(new InsertDefOperation(interface, decl, loc)));
}
return results;
return;
}
}
}
}
break;
}
}
return noResult();
}
namespace {
......@@ -333,7 +319,7 @@ namespace {
class ExtractFunctionOperation : public CppQuickFixOperation
{
public:
ExtractFunctionOperation(const QSharedPointer<const CppQuickFixAssistInterface> &interface,
ExtractFunctionOperation(const CppQuickFixInterface &interface,
int extractionStart,
int extractionEnd,
FunctionDefinitionAST *refFuncDef,
......@@ -349,10 +335,11 @@ public:
setDescription(QCoreApplication::translate("QuickFix::ExtractFunction", "Extract Function"));
}
void performChanges(const CppTools::CppRefactoringFilePtr &currentFile,
const CppTools::CppRefactoringChanges &refactoring)
void perform()
{
QTC_ASSERT(!m_funcReturn || !m_relevantDecls.isEmpty(), return);
CppRefactoringChanges refactoring(snapshot());
CppRefactoringFilePtr currentFile = refactoring.file(fileName());
const QString &funcName = getFunctionName();
if (funcName.isEmpty())
......@@ -728,14 +715,13 @@ public:
} // anonymous namespace
QList<CppQuickFixOperation::Ptr> ExtractFunction::match(
const QSharedPointer<const CppQuickFixAssistInterface> &interface)
void ExtractFunction::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
{
CppRefactoringFilePtr file = interface->currentFile();
QTextCursor cursor = file->cursor();
if (!cursor.hasSelection())
return noResult();
return;
const QList<AST *> &path = interface->path();
FunctionDefinitionAST *refFuncDef = 0; // The "reference" function, which we will extract from.
......@@ -752,7 +738,7 @@ QList<CppQuickFixOperation::Ptr> ExtractFunction::match(
|| !refFuncDef->symbol
|| !refFuncDef->symbol->name()
|| refFuncDef->symbol->enclosingScope()->isTemplate() /* TODO: Templates... */) {
return noResult();
return;
}
// Adjust selection ends.
......@@ -770,7 +756,7 @@ QList<CppQuickFixOperation::Ptr> ExtractFunction::match(
file,
printer);
if (!analyser(refFuncDef))
return noResult();
return;
// We also need to collect the declarations of the parameters from the reference function.
QSet<QString> refFuncParams;
......@@ -826,20 +812,20 @@ QList<CppQuickFixOperation::Ptr> ExtractFunction::match(
if ((usedBeforeExtraction && usedInsideExtraction)
|| (usedInsideExtraction && refFuncParams.contains(name))) {
QTC_ASSERT(analyser.m_knownDecls.contains(name), return noResult());
QTC_ASSERT(analyser.m_knownDecls.contains(name), return);
relevantDecls.append(qMakePair(name, analyser.m_knownDecls.value(name)));
}
// We assume that the first use of a local corresponds to its declaration.
if (usedInsideExtraction && usedAfterExtraction && !usedBeforeExtraction) {
if (!funcReturn) {
QTC_ASSERT(analyser.m_knownDecls.contains(name), return noResult());
QTC_ASSERT(analyser.m_knownDecls.contains(name), return);
// The return, if any, is stored as the first item in the list.
relevantDecls.prepend(qMakePair(name, analyser.m_knownDecls.value(name)));
funcReturn = it.key();
} else {
// Would require multiple returns. (Unless we do fancy things, as pointed below.)
return noResult();
return;
}
}
}
......@@ -847,10 +833,10 @@ QList<CppQuickFixOperation::Ptr> ExtractFunction::match(
// The current implementation doesn't try to be too smart since it preserves the original form
// of the declarations. This might be or not the desired effect. An improvement would be to
// let the user somehow customize the function interface.
return singleResult(new ExtractFunctionOperation(interface,
result.append(CppQuickFixOperation::Ptr(new ExtractFunctionOperation(interface,
analyser.m_extractionStart,
analyser.m_extractionEnd,
refFuncDef,
funcReturn,
relevantDecls));
relevantDecls)));
}
......@@ -38,24 +38,20 @@ namespace Internal {
class DeclFromDef: public CppQuickFixFactory
{
public:
virtual QList<CppQuickFixOperation::Ptr>
match(const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface);
void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
};
class DefFromDecl: public CppQuickFixFactory
{
public:
virtual QList<CppQuickFixOperation::Ptr>
match(const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface);
void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
};
class ExtractFunction : public CppQuickFixFactory
{
virtual QList<CppQuickFixOperation::Ptr>
match(const QSharedPointer<const CppQuickFixAssistInterface> &interface);
void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
};
} // namespace Internal
} // namespace CppEditor
......
......@@ -50,18 +50,18 @@ using namespace Utils;
using namespace CppEditor;
using namespace CppEditor::Internal;
QList<CppQuickFixOperation::Ptr> InsertQtPropertyMembers::match(
const QSharedPointer<const CppQuickFixAssistInterface> &interface)
void InsertQtPropertyMembers::match(const CppQuickFixInterface &interface,
QuickFixOperations &result)
{
const QList<AST *> &path = interface->path();
if (path.isEmpty())
return noResult();
return;
AST * const ast = path.last();
QtPropertyDeclarationAST *qtPropertyDeclaration = ast->asQtPropertyDeclaration();
if (!qtPropertyDeclaration)
return noResult();
return;
ClassSpecifierAST *klass = 0;
for (int i = path.size() - 2; i >= 0; --i) {
......@@ -70,7 +70,7 @@ QList<CppQuickFixOperation::Ptr> InsertQtPropertyMembers::match(
break;
}
if (!klass)
return noResult();
return;
CppRefactoringFilePtr file = interface->currentFile();
const QString propertyName = file->textOf(qtPropertyDeclaration->property_name);
......@@ -118,15 +118,15 @@ QList<CppQuickFixOperation::Ptr> InsertQtPropertyMembers::match(
}
if (getterName.isEmpty() && setterName.isEmpty() && signalName.isEmpty())
return noResult();
return;
return singleResult(new Operation(interface, path.size() - 1, qtPropertyDeclaration, c,
generateFlags,
getterName, setterName, signalName, storageName));
result.append(QuickFixOperation::Ptr(
new Operation(interface, path.size() - 1, qtPropertyDeclaration, c,
generateFlags, getterName, setterName, signalName, storageName)));
}
InsertQtPropertyMembers::Operation::Operation(
const QSharedPointer<const CppQuickFixAssistInterface> &interface,
const CppQuickFixInterface &interface,
int priority, QtPropertyDeclarationAST *declaration, Class *klass,
int generateFlags, const QString &getterName, const QString &setterName, const QString &signalName,
const QString &storageName)
......@@ -143,9 +143,11 @@ InsertQtPropertyMembers::Operation::Operation(
setDescription(desc);
}
void InsertQtPropertyMembers::Operation::performChanges(const CppRefactoringFilePtr &file,
const CppRefactoringChanges &refactoring)
void InsertQtPropertyMembers::Operation::perform()
{
CppRefactoringChanges refactoring(snapshot());
CppRefactoringFilePtr file = refactoring.file(fileName());
InsertionPointLocator locator(refactoring);
Utils::ChangeSet declarations;
......
......@@ -60,8 +60,7 @@ class InsertQtPropertyMembers : public CppQuickFixFactory
Q_OBJECT
public:
virtual QList<CppQuickFixOperation::Ptr>
match(const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface);
void match(const CppQuickFixInterface &interface, QuickFixOperations &result);
private:
enum GenerateFlag {
......@@ -81,8 +80,7 @@ private:
const QString &getterName, const QString &setterName, const QString &signalName,
const QString &storageName);
virtual void performChanges(const CppTools::CppRefactoringFilePtr &file,
const CppTools::CppRefactoringChanges &refactoring);
void perform();
private:
void insertAndIndent(const TextEditor::RefactoringFilePtr &file, Utils::ChangeSet *changeSet,
......
......@@ -53,23 +53,15 @@ using namespace CppEditor::Internal;
using namespace CppTools;
using namespace TextEditor;
using namespace CPlusPlus;
using namespace Utils;
CppQuickFixOperation::CppQuickFixOperation(
const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority)
CppQuickFixOperation::CppQuickFixOperation(const CppQuickFixInterface &interface, int priority)
: QuickFixOperation(priority)
, m_interface(interface)
{}
CppQuickFixOperation::~CppQuickFixOperation()
{}
void CppQuickFixOperation::perform()
Snapshot CppQuickFixOperation::snapshot() const
{
CppRefactoringChanges refactoring(m_interface->snapshot());
CppRefactoringFilePtr current = refactoring.file(fileName());
performChanges(current, refactoring);
return m_interface->snapshot();
}
const CppQuickFixAssistInterface *CppQuickFixOperation::assistInterface() const
......@@ -82,32 +74,10 @@ QString CppQuickFixOperation::fileName() const
return m_interface->document()->fileName();
}
CppQuickFixFactory::CppQuickFixFactory()
{
}
CppQuickFixFactory::~CppQuickFixFactory()
void CppQuickFixFactory::matchingOperations(const QuickFixInterface &interface, QuickFixOperations &result)
{
}
QList<QuickFixOperation::Ptr> CppQuickFixFactory::matchingOperations(
const QSharedPointer<const TextEditor::IAssistInterface> &interface)
{
QSharedPointer<const CppQuickFixAssistInterface> cppInterface =
interface.staticCast<const CppQuickFixAssistInterface>();
CppQuickFixInterface cppInterface = interface.staticCast<const CppQuickFixAssistInterface>();
if (cppInterface->path().isEmpty())
return QList<QuickFixOperation::Ptr>();
return match(cppInterface);
}
QList<CppQuickFixOperation::Ptr> CppQuickFixFactory::singleResult(CppQuickFixOperation *operation)
{
QList<CppQuickFixOperation::Ptr> result;
result.append(CppQuickFixOperation::Ptr(operation));
return result;
}
QList<CppQuickFixOperation::Ptr> CppQuickFixFactory::noResult()
{
return QList<CppQuickFixOperation::Ptr>();
return;
match(cppInterface, result);
}
......@@ -35,44 +35,28 @@
namespace CPlusPlus {
class CppModelManagerInterface;
}
namespace CppTools {
class CppRefactoringFile;
class CppRefactoringChanges;
typedef QSharedPointer<CppRefactoringFile> CppRefactoringFilePtr;
} // namespace CppTools
namespace ExtensionSystem {
class IPlugin;
class Snapshot;
}
namespace CppEditor {
namespace Internal { class CppQuickFixAssistInterface; }
namespace Internal {
class CppQuickFixAssistInterface;
}
typedef QSharedPointer<const Internal::CppQuickFixAssistInterface> CppQuickFixInterface;
typedef TextEditor::QuickFixInterface QuickFixInterface;
typedef TextEditor::QuickFixOperations QuickFixOperations;
class CPPEDITOR_EXPORT CppQuickFixOperation: public TextEditor::QuickFixOperation
{
public:
explicit CppQuickFixOperation(
const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface,
int priority = -1);
virtual ~CppQuickFixOperation();
virtual void perform();
explicit CppQuickFixOperation(const CppQuickFixInterface &interface, int priority = -1);
protected:
virtual void performChanges(const CppTools::CppRefactoringFilePtr &currentFile,
const CppTools::CppRefactoringChanges &refactoring) = 0;
QString fileName() const;
CPlusPlus::Snapshot snapshot() const;
const Internal::CppQuickFixAssistInterface *assistInterface() const;
private:
QSharedPointer<const Internal::CppQuickFixAssistInterface> m_interface;
CppQuickFixInterface m_interface;
};
class CPPEDITOR_EXPORT CppQuickFixFactory: public TextEditor::QuickFixFactory
......@@ -80,29 +64,15 @@ class CPPEDITOR_EXPORT CppQuickFixFactory: public TextEditor::QuickFixFactory
Q_OBJECT
public: