Skip to content
Snippets Groups Projects
Commit ac9fc406 authored by Erik Verbruggen's avatar Erik Verbruggen
Browse files

C++ Editor: check for method existing decl/def when inserting new ones.

parent 0555837c
No related branches found
No related tags found
No related merge requests found
......@@ -132,6 +132,8 @@ public:
{
Function *funTy = control()->newFunction(0, 0);
funTy->copy(type);
funTy->setConst(type->isConst());
funTy->setVolatile(type->isVolatile());
funTy->setName(rewrite->rewriteName(type->name()));
......
......@@ -29,12 +29,7 @@
#include "cppinsertdecldef.h"
#include <AST.h>
#include <ASTVisitor.h>
#include <CoreTypes.h>
#include <Names.h>
#include <Symbols.h>
#include <TranslationUnit.h>
#include <CPlusPlus.h>
#include <cplusplus/ASTPath.h>
#include <cplusplus/CppRewriter.h>
#include <cplusplus/LookupContext.h>
......@@ -42,6 +37,7 @@
#include <cpptools/insertionpointlocator.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
using namespace CPlusPlus;
using namespace CppEditor;
......@@ -142,46 +138,49 @@ QList<CppQuickFixOperation::Ptr> DeclFromDef::match(const CppQuickFixState &stat
Function *method = funDef->symbol;
if (ClassOrNamespace *targetBinding = state.context().lookupParent(method)) {
foreach (Symbol *s, targetBinding->symbols()) {
if (Class *clazz = s->asClass()) {
QList<CppQuickFixOperation::Ptr> results;
const QString fn = QString::fromUtf8(clazz->fileName(), clazz->fileNameLength());
Scope *enclosingScope = method->enclosingScope();
while (! (enclosingScope->isNamespace() || enclosingScope->isClass()))
enclosingScope = enclosingScope->enclosingScope();
Q_ASSERT(enclosingScope != 0);
const Name *functionName = method->name();
if (! functionName)
return noResult(); // warn, anonymous function names are not valid c++
if (! functionName->isQualifiedNameId())
return noResult(); // warn, trying to add a declaration for a global function
const QualifiedNameId *q = functionName->asQualifiedNameId();
if (!q->base())
return noResult();
if (ClassOrNamespace *binding = state.context().lookupType(q->base(), enclosingScope)) {
foreach (Symbol *s, binding->symbols()) {
if (Class *matchingClass = s->asClass()) {
for (Symbol *s = matchingClass->find(q->identifier()); s; s = s->next()) {
if (! s->name())
continue;
else if (! q->identifier()->isEqualTo(s->identifier()))
continue;
else if (! s->type()->isFunctionType())
continue;
if (s->type().isEqualTo(method->type()))
return noResult();
}
// a good candidate
const QString fn = QString::fromUtf8(matchingClass->fileName(),
matchingClass->fileNameLength());
const QString decl = generateDeclaration(state,
method,
targetBinding);
results.append(
singleResult(
new InsertDeclOperation(state, idx, fn, clazz,
InsertionPointLocator::Public,
decl)));
// results.append(
// singleResult(
// new InsertDeclOperation(state, idx, fn, clazz,
// InsertionPointLocator::Protected,
// decl)));
// results.append(
// singleResult(
// new InsertDeclOperation(state, idx, fn, clazz,
// InsertionPointLocator::Private,
// decl)));
// results.append(
// singleResult(
// new InsertDeclOperation(state, idx, fn, clazz,
// InsertionPointLocator::PublicSlot,
// decl)));
// results.append(
// singleResult(
// new InsertDeclOperation(state, idx, fn, clazz,
// InsertionPointLocator::ProtectedSlot,
// decl)));
// results.append(
// singleResult(
// new InsertDeclOperation(state, idx, fn, clazz,
// InsertionPointLocator::PrivateSlot,
// decl)));
return results;
} //! \todo support insertion of non-methods into namespaces
binding);
return singleResult(
new InsertDeclOperation(state, idx, fn, matchingClass,
InsertionPointLocator::Public,
decl));
}
}
}
......@@ -217,9 +216,11 @@ public:
, m_decl(decl)
, m_loc(loc)
{
const QString declFile = QString::fromUtf8(decl->fileName(), decl->fileNameLength());
const QDir dir = QFileInfo(declFile).dir();
setDescription(QCoreApplication::translate("CppEditor::InsertDefOperation",
"Add definition in %1")
.arg(m_loc.fileName()));
.arg(dir.relativeFilePath(m_loc.fileName())));
}
void performChanges(CppRefactoringFile *,
......
......@@ -104,7 +104,8 @@ CppRefactoringFile::CppRefactoringFile(TextEditor::BaseTextEditor *editor, CPlus
Document::Ptr CppRefactoringFile::cppDocument() const
{
if (!m_cppDocument) {
if (!m_cppDocument || !m_cppDocument->translationUnit() ||
!m_cppDocument->translationUnit()->ast()) {
const QString source = document()->toPlainText();
const QString name = fileName();
const Snapshot &snapshot = refactoringChanges()->snapshot();
......
......@@ -315,6 +315,7 @@ static bool isSourceFile(const QString &fileName)
}
/// Currently, we return the end of fileName.cpp
/// \todo take the definitions of the surrounding declarations into account
QList<InsertionLocation> InsertionPointLocator::methodDefinition(
Declaration *declaration) const
{
......@@ -334,6 +335,15 @@ QList<InsertionLocation> InsertionPointLocator::methodDefinition(
if (doc.isNull())
return result;
Snapshot simplified = m_refactoringChanges->snapshot().simplified(doc);
if (Symbol *s = simplified.findMatchingDefinition(declaration)) {
if (Function *f = s->asFunction()) {
if (f->isConst() == declaration->type().isConst()
&& f->isVolatile() == declaration->type().isVolatile())
return result;
}
}
TranslationUnit *xUnit = doc->translationUnit();
unsigned tokenCount = xUnit->tokenCount();
if (tokenCount < 2) // no tokens available
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment