2010-07-08 16:40:46 +02:00
|
|
|
/**************************************************************************
|
|
|
|
|
**
|
|
|
|
|
** This file is part of Qt Creator
|
|
|
|
|
**
|
|
|
|
|
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
|
|
|
|
**
|
|
|
|
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
|
|
|
|
**
|
|
|
|
|
** Commercial Usage
|
|
|
|
|
**
|
|
|
|
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
|
|
|
|
** accordance with the Qt Commercial License Agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
|
|
|
** a written agreement between you and Nokia.
|
|
|
|
|
**
|
|
|
|
|
** 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.
|
|
|
|
|
**
|
|
|
|
|
** If you are unsure which license is appropriate for your use, please
|
|
|
|
|
** contact the sales department at http://qt.nokia.com/contact.
|
|
|
|
|
**
|
|
|
|
|
**************************************************************************/
|
|
|
|
|
|
|
|
|
|
#include "cppdeclfromdef.h"
|
|
|
|
|
|
|
|
|
|
#include <Literals.h> //### remove
|
|
|
|
|
#include <QDebug> //###remove
|
|
|
|
|
|
|
|
|
|
#include <AST.h>
|
|
|
|
|
#include <ASTVisitor.h>
|
|
|
|
|
#include <CoreTypes.h>
|
|
|
|
|
#include <Names.h>
|
|
|
|
|
#include <Symbols.h>
|
|
|
|
|
#include <TranslationUnit.h>
|
|
|
|
|
#include <cplusplus/ASTPath.h>
|
2010-07-27 15:29:16 +02:00
|
|
|
#include <cplusplus/InsertionPointLocator.h>
|
2010-07-08 16:40:46 +02:00
|
|
|
#include <cplusplus/LookupContext.h>
|
|
|
|
|
#include <cplusplus/Overview.h>
|
|
|
|
|
|
|
|
|
|
#include <QtCore/QCoreApplication>
|
|
|
|
|
|
|
|
|
|
using namespace CPlusPlus;
|
2010-07-26 13:06:33 +02:00
|
|
|
using namespace CppEditor;
|
2010-07-08 16:40:46 +02:00
|
|
|
using namespace CppEditor::Internal;
|
|
|
|
|
using namespace CppTools;
|
|
|
|
|
|
|
|
|
|
using CppEditor::CppRefactoringChanges;
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
QString prettyMinimalType(const FullySpecifiedType &ty,
|
|
|
|
|
const LookupContext &context,
|
|
|
|
|
Scope *source,
|
|
|
|
|
ClassOrNamespace *target)
|
|
|
|
|
{
|
|
|
|
|
Overview oo;
|
|
|
|
|
|
|
|
|
|
if (const NamedType *namedTy = ty->asNamedType())
|
|
|
|
|
return oo.prettyTypeWithName(ty, context.minimalName(namedTy->name(),
|
|
|
|
|
source,
|
|
|
|
|
target),
|
|
|
|
|
context.control().data());
|
|
|
|
|
else
|
|
|
|
|
return oo(ty);
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-26 13:06:33 +02:00
|
|
|
class Operation: public CppQuickFixOperation
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
Operation(const CppQuickFixState &state, int priority,
|
2010-07-27 15:29:16 +02:00
|
|
|
const QString &targetFileName, const Class *targetSymbol,
|
2010-07-26 13:06:33 +02:00
|
|
|
const QString &decl)
|
|
|
|
|
: CppQuickFixOperation(state, priority)
|
|
|
|
|
, m_targetFileName(targetFileName)
|
2010-07-27 15:29:16 +02:00
|
|
|
, m_targetSymbol(targetSymbol)
|
2010-07-26 13:06:33 +02:00
|
|
|
, m_decl(decl)
|
|
|
|
|
{
|
|
|
|
|
setDescription(QCoreApplication::tr("Create Declaration from Definition",
|
|
|
|
|
"CppEditor::DeclFromDef"));
|
|
|
|
|
}
|
2010-07-08 16:40:46 +02:00
|
|
|
|
2010-07-26 13:06:33 +02:00
|
|
|
void createChanges()
|
|
|
|
|
{
|
|
|
|
|
CppRefactoringChanges *changes = refactoringChanges();
|
2010-07-08 16:40:46 +02:00
|
|
|
|
2010-07-26 13:06:33 +02:00
|
|
|
Document::Ptr targetDoc = changes->document(m_targetFileName);
|
2010-07-27 15:29:16 +02:00
|
|
|
InsertionPointLocator locator(targetDoc);
|
|
|
|
|
const InsertionLocation loc = locator.methodDeclarationInClass(m_targetSymbol, InsertionPointLocator::Public);
|
2010-07-26 13:06:33 +02:00
|
|
|
|
2010-07-27 15:29:16 +02:00
|
|
|
int targetPosition1 = changes->positionInFile(m_targetFileName, loc.line() - 1, loc.column() - 1);
|
|
|
|
|
int targetPosition2 = changes->positionInFile(m_targetFileName, loc.line(), 0) - 1;
|
2010-07-26 13:06:33 +02:00
|
|
|
|
|
|
|
|
Utils::ChangeSet target;
|
2010-07-27 15:29:16 +02:00
|
|
|
target.insert(targetPosition1, loc.prefix() + m_decl);
|
2010-07-26 13:06:33 +02:00
|
|
|
changes->changeFile(m_targetFileName, target);
|
|
|
|
|
|
|
|
|
|
changes->reindent(m_targetFileName,
|
|
|
|
|
Utils::ChangeSet::Range(targetPosition1, targetPosition2));
|
|
|
|
|
|
2010-07-27 15:29:16 +02:00
|
|
|
changes->openEditor(m_targetFileName, loc.line() - 1, loc.column() - 1);
|
2010-07-26 13:06:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
QString m_targetFileName;
|
2010-07-27 15:29:16 +02:00
|
|
|
const Class *m_targetSymbol;
|
2010-07-26 13:06:33 +02:00
|
|
|
QString m_decl;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // anonymous namespace
|
2010-07-08 16:40:46 +02:00
|
|
|
|
2010-07-26 13:06:33 +02:00
|
|
|
QList<CppQuickFixOperation::Ptr> DeclFromDef::match(const CppQuickFixState &state)
|
2010-07-08 16:40:46 +02:00
|
|
|
{
|
2010-07-26 13:06:33 +02:00
|
|
|
const QList<AST *> &path = state.path();
|
2010-07-08 16:40:46 +02:00
|
|
|
|
|
|
|
|
FunctionDefinitionAST *funDef = 0;
|
|
|
|
|
int idx = 0;
|
|
|
|
|
for (; idx < path.size(); ++idx) {
|
|
|
|
|
AST *node = path.at(idx);
|
2010-07-13 14:36:14 +02:00
|
|
|
if (FunctionDefinitionAST *candidate = node->asFunctionDefinition()) {
|
2010-07-27 15:29:16 +02:00
|
|
|
if (!funDef && state.isCursorOn(candidate) && !state.isCursorOn(candidate->function_body))
|
2010-07-08 16:40:46 +02:00
|
|
|
funDef = candidate;
|
2010-07-13 14:36:14 +02:00
|
|
|
} else if (node->asClassSpecifier()) {
|
2010-07-26 13:06:33 +02:00
|
|
|
return noResult();
|
2010-07-13 14:36:14 +02:00
|
|
|
}
|
2010-07-08 16:40:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!funDef || !funDef->symbol)
|
2010-07-26 13:06:33 +02:00
|
|
|
return noResult();
|
2010-07-08 16:40:46 +02:00
|
|
|
|
|
|
|
|
Function *method = funDef->symbol;
|
|
|
|
|
|
2010-07-26 13:06:33 +02:00
|
|
|
if (ClassOrNamespace *targetBinding = state.context().lookupParent(method)) {
|
2010-07-08 16:40:46 +02:00
|
|
|
foreach (Symbol *s, targetBinding->symbols()) {
|
|
|
|
|
if (Class *clazz = s->asClass()) {
|
2010-07-26 13:06:33 +02:00
|
|
|
return singleResult(new Operation(state, idx,
|
|
|
|
|
QLatin1String(clazz->fileName()),
|
2010-07-27 15:29:16 +02:00
|
|
|
clazz,
|
2010-07-26 13:06:33 +02:00
|
|
|
generateDeclaration(state,
|
|
|
|
|
method,
|
|
|
|
|
targetBinding)));
|
2010-07-08 16:40:46 +02:00
|
|
|
} // ### TODO: support insertion into namespaces
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-26 13:06:33 +02:00
|
|
|
return noResult();
|
2010-07-08 16:40:46 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-26 13:06:33 +02:00
|
|
|
QString DeclFromDef::generateDeclaration(const CppQuickFixState &state,
|
|
|
|
|
Function *method,
|
|
|
|
|
ClassOrNamespace *targetBinding)
|
2010-07-08 16:40:46 +02:00
|
|
|
{
|
|
|
|
|
Overview oo;
|
|
|
|
|
QString decl;
|
|
|
|
|
|
|
|
|
|
decl.append(prettyMinimalType(method->returnType(),
|
2010-07-26 13:06:33 +02:00
|
|
|
state.context(),
|
2010-07-08 16:40:46 +02:00
|
|
|
method->scope(),
|
|
|
|
|
targetBinding));
|
|
|
|
|
|
|
|
|
|
decl.append(QLatin1Char(' '));
|
|
|
|
|
decl.append(QLatin1String(method->name()->identifier()->chars()));
|
|
|
|
|
decl.append(QLatin1Char('('));
|
|
|
|
|
for (unsigned argIdx = 0; argIdx < method->argumentCount(); ++argIdx) {
|
|
|
|
|
if (argIdx > 0)
|
|
|
|
|
decl.append(QLatin1String(", "));
|
|
|
|
|
Argument *arg = method->argumentAt(argIdx)->asArgument();
|
|
|
|
|
decl.append(prettyMinimalType(arg->type(),
|
2010-07-26 13:06:33 +02:00
|
|
|
state.context(),
|
2010-07-08 16:40:46 +02:00
|
|
|
method->members(),
|
|
|
|
|
targetBinding));
|
|
|
|
|
decl.append(QLatin1Char(' '));
|
|
|
|
|
decl.append(oo(arg->name()));
|
|
|
|
|
}
|
|
|
|
|
decl.append(QLatin1String(");\n\n"));
|
|
|
|
|
|
|
|
|
|
return decl;
|
|
|
|
|
}
|