forked from qt-creator/qt-creator
		
	C++: Synchronize function decl/def refactoring.
When editing a function declaration or definition the code model may realize the same changes have to be applied somewhere else. A refactoring marker will pop up that can be clicked to perform the changes. Alternatively, press enter to apply. Change-Id: I2299a2ecfb6a8f87d4853fc7cfa99486f890a1d3 Reviewed-on: http://codereview.qt.nokia.com/2909 Reviewed-by: Leandro T. C. Melo <leandro.melo@nokia.com>
This commit is contained in:
		@@ -50,6 +50,7 @@
 | 
			
		||||
#include <NameVisitor.h>
 | 
			
		||||
#include <TypeVisitor.h>
 | 
			
		||||
#include <CoreTypes.h>
 | 
			
		||||
#include <LookupContext.h>
 | 
			
		||||
 | 
			
		||||
#include <QtCore/QByteArray>
 | 
			
		||||
#include <QtCore/QBitArray>
 | 
			
		||||
@@ -583,6 +584,8 @@ void Document::check(CheckMode mode)
 | 
			
		||||
        semantic(ast, _globalNamespace);
 | 
			
		||||
    } else if (ExpressionAST *ast = _translationUnit->ast()->asExpression()) {
 | 
			
		||||
        semantic(ast, _globalNamespace);
 | 
			
		||||
    } else if (DeclarationAST *ast = translationUnit()->ast()->asDeclaration()) {
 | 
			
		||||
        semantic(ast, _globalNamespace);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -972,7 +975,9 @@ public:
 | 
			
		||||
};
 | 
			
		||||
} // end of anonymous namespace
 | 
			
		||||
 | 
			
		||||
Symbol *Snapshot::findMatchingDefinition(Symbol *declaration) const
 | 
			
		||||
// strict means the returned symbol has to match exactly,
 | 
			
		||||
// including argument count and argument types
 | 
			
		||||
Symbol *Snapshot::findMatchingDefinition(Symbol *declaration, bool strict) const
 | 
			
		||||
{
 | 
			
		||||
    if (!declaration)
 | 
			
		||||
        return 0;
 | 
			
		||||
@@ -1030,7 +1035,7 @@ Symbol *Snapshot::findMatchingDefinition(Symbol *declaration) const
 | 
			
		||||
            if (viableFunctions.isEmpty())
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            else if (viableFunctions.length() == 1)
 | 
			
		||||
            else if (! strict && viableFunctions.length() == 1)
 | 
			
		||||
                return viableFunctions.first();
 | 
			
		||||
 | 
			
		||||
            Function *best = 0;
 | 
			
		||||
@@ -1039,7 +1044,7 @@ Symbol *Snapshot::findMatchingDefinition(Symbol *declaration) const
 | 
			
		||||
                if (! (fun->unqualifiedName() && fun->unqualifiedName()->isEqualTo(declaration->unqualifiedName())))
 | 
			
		||||
                    continue;
 | 
			
		||||
                else if (fun->argumentCount() == declarationTy->argumentCount()) {
 | 
			
		||||
                    if (! best)
 | 
			
		||||
                    if (! strict && ! best)
 | 
			
		||||
                        best = fun;
 | 
			
		||||
 | 
			
		||||
                    unsigned argc = 0;
 | 
			
		||||
@@ -1055,7 +1060,7 @@ Symbol *Snapshot::findMatchingDefinition(Symbol *declaration) const
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (! best)
 | 
			
		||||
            if (!strict && ! best)
 | 
			
		||||
                best = viableFunctions.first();
 | 
			
		||||
 | 
			
		||||
            return best;
 | 
			
		||||
@@ -1089,3 +1094,74 @@ Class *Snapshot::findMatchingClassDeclaration(Symbol *declaration) const
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CPlusPlus::findMatchingDeclaration(const LookupContext &context,
 | 
			
		||||
                                        Function *functionType,
 | 
			
		||||
                                        QList<Declaration *> *typeMatch,
 | 
			
		||||
                                        QList<Declaration *> *argumentCountMatch,
 | 
			
		||||
                                        QList<Declaration *> *nameMatch)
 | 
			
		||||
{
 | 
			
		||||
    Scope *enclosingScope = functionType->enclosingScope();
 | 
			
		||||
    while (! (enclosingScope->isNamespace() || enclosingScope->isClass()))
 | 
			
		||||
        enclosingScope = enclosingScope->enclosingScope();
 | 
			
		||||
    Q_ASSERT(enclosingScope != 0);
 | 
			
		||||
 | 
			
		||||
    const Name *functionName = functionType->name();
 | 
			
		||||
    if (! functionName)
 | 
			
		||||
        return; // anonymous function names are not valid c++
 | 
			
		||||
 | 
			
		||||
    ClassOrNamespace *binding = 0;
 | 
			
		||||
    const QualifiedNameId *qName = functionName->asQualifiedNameId();
 | 
			
		||||
    if (qName) {
 | 
			
		||||
        if (qName->base())
 | 
			
		||||
            binding = context.lookupType(qName->base(), enclosingScope);
 | 
			
		||||
        functionName = qName->name();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!binding) { // declaration for a global function
 | 
			
		||||
        binding = context.lookupType(enclosingScope);
 | 
			
		||||
 | 
			
		||||
        if (!binding)
 | 
			
		||||
            return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const Identifier *funcId = functionName->identifier();
 | 
			
		||||
    if (!funcId) // E.g. operator, which we might be able to handle in the future...
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    foreach (Symbol *s, binding->symbols()) {
 | 
			
		||||
        Class *matchingClass = s->asClass();
 | 
			
		||||
        if (!matchingClass)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        for (Symbol *s = matchingClass->find(funcId); s; s = s->next()) {
 | 
			
		||||
            if (! s->name())
 | 
			
		||||
                continue;
 | 
			
		||||
            else if (! funcId->isEqualTo(s->identifier()))
 | 
			
		||||
                continue;
 | 
			
		||||
            else if (! s->type()->isFunctionType())
 | 
			
		||||
                continue;
 | 
			
		||||
            else if (Declaration *decl = s->asDeclaration()) {
 | 
			
		||||
                if (Function *declFunTy = decl->type()->asFunctionType()) {
 | 
			
		||||
                    if (functionType->isEqualTo(declFunTy))
 | 
			
		||||
                        typeMatch->prepend(decl);
 | 
			
		||||
                    else if (functionType->argumentCount() == declFunTy->argumentCount())
 | 
			
		||||
                        argumentCountMatch->prepend(decl);
 | 
			
		||||
                    else
 | 
			
		||||
                        nameMatch->append(decl);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QList<Declaration *> CPlusPlus::findMatchingDeclaration(const LookupContext &context, Function *functionType)
 | 
			
		||||
{
 | 
			
		||||
    QList<Declaration *> result;
 | 
			
		||||
    QList<Declaration *> nameMatch, argumentCountMatch, typeMatch;
 | 
			
		||||
    findMatchingDeclaration(context, functionType, &typeMatch, &argumentCountMatch, &nameMatch);
 | 
			
		||||
    result.append(typeMatch);
 | 
			
		||||
    result.append(argumentCountMatch);
 | 
			
		||||
    result.append(nameMatch);
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -45,6 +45,7 @@ namespace CPlusPlus {
 | 
			
		||||
 | 
			
		||||
class Macro;
 | 
			
		||||
class MacroArgumentReference;
 | 
			
		||||
class LookupContext;
 | 
			
		||||
 | 
			
		||||
class CPLUSPLUS_EXPORT Document
 | 
			
		||||
{
 | 
			
		||||
@@ -386,7 +387,7 @@ public:
 | 
			
		||||
    Document::Ptr documentFromSource(const QByteArray &preprocessedCode,
 | 
			
		||||
                                     const QString &fileName) const;
 | 
			
		||||
 | 
			
		||||
    Symbol *findMatchingDefinition(Symbol *symbol) const;
 | 
			
		||||
    Symbol *findMatchingDefinition(Symbol *symbol, bool strict = false) const;
 | 
			
		||||
    Class *findMatchingClassDeclaration(Symbol *symbol) const;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
@@ -396,6 +397,15 @@ private:
 | 
			
		||||
    _Base _documents;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void CPLUSPLUS_EXPORT findMatchingDeclaration(
 | 
			
		||||
        const LookupContext &context,
 | 
			
		||||
        Function *functionType,
 | 
			
		||||
        QList<Declaration *> *typeMatch,
 | 
			
		||||
        QList<Declaration *> *argumentCountMatch,
 | 
			
		||||
        QList<Declaration *> *nameMatch);
 | 
			
		||||
QList<Declaration *> CPLUSPLUS_EXPORT findMatchingDeclaration(
 | 
			
		||||
        const LookupContext &context, Function *functionType);
 | 
			
		||||
 | 
			
		||||
} // namespace CPlusPlus
 | 
			
		||||
 | 
			
		||||
#endif // CPLUSPLUS_CPPDOCUMENT_H
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user