forked from qt-creator/qt-creator
Find the canonical virtual method.
This commit is contained in:
@@ -30,6 +30,7 @@
|
|||||||
#include "LookupContext.h"
|
#include "LookupContext.h"
|
||||||
#include "ResolveExpression.h"
|
#include "ResolveExpression.h"
|
||||||
#include "Overview.h"
|
#include "Overview.h"
|
||||||
|
#include "CppBindings.h"
|
||||||
|
|
||||||
#include <CoreTypes.h>
|
#include <CoreTypes.h>
|
||||||
#include <Symbols.h>
|
#include <Symbols.h>
|
||||||
@@ -501,6 +502,97 @@ void LookupContext::expand(Scope *scope,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void visibleClassBindings_helper(ClassBinding *classBinding,
|
||||||
|
QList<ClassBinding *> *allClassBindings,
|
||||||
|
QSet<ClassBinding *> *processed)
|
||||||
|
{
|
||||||
|
if (! classBinding)
|
||||||
|
return;
|
||||||
|
|
||||||
|
else if (processed->contains(classBinding))
|
||||||
|
return;
|
||||||
|
|
||||||
|
processed->insert(classBinding);
|
||||||
|
|
||||||
|
foreach (ClassBinding *baseClassBinding, classBinding->baseClassBindings)
|
||||||
|
visibleClassBindings_helper(baseClassBinding, allClassBindings, processed);
|
||||||
|
|
||||||
|
allClassBindings->append(classBinding);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QList<ClassBinding *> visibleClassBindings(Symbol *symbol, NamespaceBinding *globalNamespace)
|
||||||
|
{
|
||||||
|
QList<ClassBinding *> classBindings;
|
||||||
|
|
||||||
|
if (! symbol)
|
||||||
|
return classBindings;
|
||||||
|
|
||||||
|
else if (Class *klass = symbol->asClass()) {
|
||||||
|
QSet<ClassBinding *> processed;
|
||||||
|
|
||||||
|
visibleClassBindings_helper(NamespaceBinding::find(klass, globalNamespace),
|
||||||
|
&classBindings, &processed);
|
||||||
|
}
|
||||||
|
|
||||||
|
return classBindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
Symbol *LookupContext::canonicalSymbol(Symbol *symbol,
|
||||||
|
NamespaceBinding *globalNamespace)
|
||||||
|
{
|
||||||
|
Symbol *canonicalSymbol = LookupContext::canonicalSymbol(symbol);
|
||||||
|
|
||||||
|
if (Identifier *symbolId = canonicalSymbol->identifier()) {
|
||||||
|
if (symbolId && canonicalSymbol->type()->isFunctionType()) {
|
||||||
|
Class *enclosingClass = canonicalSymbol->scope()->owner()->asClass();
|
||||||
|
const QList<ClassBinding *> classBindings = visibleClassBindings(enclosingClass, globalNamespace);
|
||||||
|
|
||||||
|
foreach (ClassBinding *baseClassBinding, classBindings) {
|
||||||
|
if (! baseClassBinding)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (Class *baseClass, baseClassBinding->symbols) {
|
||||||
|
if (! baseClass)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (Symbol *c = baseClass->members()->lookat(symbolId); c; c = c->next()) {
|
||||||
|
if (! symbolId->isEqualTo(c->identifier()))
|
||||||
|
continue;
|
||||||
|
else if (Function *f = c->type()->asFunctionType()) {
|
||||||
|
if (f->isVirtual())
|
||||||
|
return LookupContext::canonicalSymbol(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return canonicalSymbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
Symbol *LookupContext::canonicalSymbol(const QList<Symbol *> &candidates,
|
||||||
|
NamespaceBinding *globalNamespaceBinding)
|
||||||
|
{
|
||||||
|
if (candidates.isEmpty())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return canonicalSymbol(candidates.first(), globalNamespaceBinding);
|
||||||
|
}
|
||||||
|
|
||||||
|
Symbol *LookupContext::canonicalSymbol(const QList<QPair<FullySpecifiedType, Symbol *> > &results,
|
||||||
|
NamespaceBinding *globalNamespaceBinding)
|
||||||
|
{
|
||||||
|
QList<Symbol *> candidates;
|
||||||
|
QPair<FullySpecifiedType, Symbol *> result;
|
||||||
|
|
||||||
|
foreach (result, results)
|
||||||
|
candidates.append(result.second); // ### not exacly.
|
||||||
|
|
||||||
|
return canonicalSymbol(candidates, globalNamespaceBinding);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Symbol *LookupContext::canonicalSymbol(Symbol *symbol)
|
Symbol *LookupContext::canonicalSymbol(Symbol *symbol)
|
||||||
{
|
{
|
||||||
Symbol *canonical = symbol;
|
Symbol *canonical = symbol;
|
||||||
@@ -531,22 +623,3 @@ Symbol *LookupContext::canonicalSymbol(Symbol *symbol)
|
|||||||
|
|
||||||
return canonical;
|
return canonical;
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol *LookupContext::canonicalSymbol(const QList<Symbol *> &candidates)
|
|
||||||
{
|
|
||||||
if (candidates.isEmpty())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return canonicalSymbol(candidates.first());
|
|
||||||
}
|
|
||||||
|
|
||||||
Symbol *LookupContext::canonicalSymbol(const QList<QPair<FullySpecifiedType, Symbol *> > &results)
|
|
||||||
{
|
|
||||||
QList<Symbol *> candidates;
|
|
||||||
QPair<FullySpecifiedType, Symbol *> result;
|
|
||||||
|
|
||||||
foreach (result, results)
|
|
||||||
candidates.append(result.second); // ### not exacly.
|
|
||||||
|
|
||||||
return canonicalSymbol(candidates);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -54,9 +54,14 @@ public:
|
|||||||
Document::Ptr document(const QString &fileName) const;
|
Document::Ptr document(const QString &fileName) const;
|
||||||
Snapshot snapshot() const;
|
Snapshot snapshot() const;
|
||||||
|
|
||||||
static Symbol *canonicalSymbol(Symbol *symbol);
|
static Symbol *canonicalSymbol(const QList<Symbol *> &candidates,
|
||||||
static Symbol *canonicalSymbol(const QList<Symbol *> &candidates);
|
NamespaceBinding *globalNamespaceBinding);
|
||||||
static Symbol *canonicalSymbol(const QList<QPair<FullySpecifiedType, Symbol *> > &candidates); // ### FIXME
|
|
||||||
|
static Symbol *canonicalSymbol(Symbol *symbol,
|
||||||
|
NamespaceBinding *globalNamespaceBinding);
|
||||||
|
|
||||||
|
static Symbol *canonicalSymbol(const QList<QPair<FullySpecifiedType, Symbol *> > &candidates,
|
||||||
|
NamespaceBinding *globalNamespaceBinding);
|
||||||
|
|
||||||
QList<Symbol *> resolve(Name *name) const
|
QList<Symbol *> resolve(Name *name) const
|
||||||
{ return resolve(name, visibleScopes()); }
|
{ return resolve(name, visibleScopes()); }
|
||||||
@@ -126,6 +131,8 @@ public:
|
|||||||
QList<Scope *> *expandedScopes) const;
|
QList<Scope *> *expandedScopes) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static Symbol *canonicalSymbol(Symbol *symbol);
|
||||||
|
|
||||||
QList<Symbol *> resolveQualifiedNameId(QualifiedNameId *q,
|
QList<Symbol *> resolveQualifiedNameId(QualifiedNameId *q,
|
||||||
const QList<Scope *> &visibleScopes,
|
const QList<Scope *> &visibleScopes,
|
||||||
ResolveMode mode) const;
|
ResolveMode mode) const;
|
||||||
|
|||||||
@@ -58,6 +58,7 @@
|
|||||||
#include <cplusplus/MatchingText.h>
|
#include <cplusplus/MatchingText.h>
|
||||||
#include <cplusplus/BackwardsScanner.h>
|
#include <cplusplus/BackwardsScanner.h>
|
||||||
#include <cplusplus/FastPreprocessor.h>
|
#include <cplusplus/FastPreprocessor.h>
|
||||||
|
#include <cplusplus/CppBindings.h>
|
||||||
|
|
||||||
#include <cpptools/cppmodelmanagerinterface.h>
|
#include <cpptools/cppmodelmanagerinterface.h>
|
||||||
|
|
||||||
@@ -838,8 +839,6 @@ CPlusPlus::Symbol *CPPEditor::findCanonicalSymbol(const QTextCursor &cursor,
|
|||||||
const QString code = expressionUnderCursor(tc);
|
const QString code = expressionUnderCursor(tc);
|
||||||
// qDebug() << "code:" << code;
|
// qDebug() << "code:" << code;
|
||||||
|
|
||||||
const QString fileName = const_cast<CPPEditor *>(this)->file()->fileName();
|
|
||||||
|
|
||||||
TypeOfExpression typeOfExpression;
|
TypeOfExpression typeOfExpression;
|
||||||
typeOfExpression.setSnapshot(snapshot);
|
typeOfExpression.setSnapshot(snapshot);
|
||||||
|
|
||||||
@@ -849,7 +848,8 @@ CPlusPlus::Symbol *CPPEditor::findCanonicalSymbol(const QTextCursor &cursor,
|
|||||||
lastVisibleSymbol,
|
lastVisibleSymbol,
|
||||||
TypeOfExpression::Preprocess);
|
TypeOfExpression::Preprocess);
|
||||||
|
|
||||||
Symbol *canonicalSymbol = LookupContext::canonicalSymbol(results);
|
NamespaceBindingPtr glo = bind(doc, snapshot);
|
||||||
|
Symbol *canonicalSymbol = LookupContext::canonicalSymbol(results, glo.data());
|
||||||
return canonicalSymbol;
|
return canonicalSymbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -152,7 +152,8 @@ protected:
|
|||||||
|
|
||||||
bool checkCandidates(const QList<Symbol *> &candidates) const
|
bool checkCandidates(const QList<Symbol *> &candidates) const
|
||||||
{
|
{
|
||||||
if (Symbol *canonicalSymbol = LookupContext::canonicalSymbol(candidates)) {
|
if (Symbol *canonicalSymbol = LookupContext::canonicalSymbol(candidates, _globalNamespaceBinding.data())) {
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
qDebug() << "*** canonical symbol:" << canonicalSymbol->fileName()
|
qDebug() << "*** canonical symbol:" << canonicalSymbol->fileName()
|
||||||
<< canonicalSymbol->line() << canonicalSymbol->column()
|
<< canonicalSymbol->line() << canonicalSymbol->column()
|
||||||
@@ -498,7 +499,7 @@ static void find_helper(QFutureInterface<Utils::FileSearchResult> &future,
|
|||||||
files += snapshot.dependsOn(sourceFile);
|
files += snapshot.dependsOn(sourceFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "done in:" << tm.elapsed() << "number of files to parse:" << files.size();
|
//qDebug() << "done in:" << tm.elapsed() << "number of files to parse:" << files.size();
|
||||||
|
|
||||||
future.setProgressRange(0, files.size());
|
future.setProgressRange(0, files.size());
|
||||||
|
|
||||||
|
|||||||
@@ -752,7 +752,8 @@ QList<int> CppModelManager::references(CPlusPlus::Symbol *symbol,
|
|||||||
CPlusPlus::Document::Ptr doc,
|
CPlusPlus::Document::Ptr doc,
|
||||||
const CPlusPlus::Snapshot &snapshot)
|
const CPlusPlus::Snapshot &snapshot)
|
||||||
{
|
{
|
||||||
return m_findReferences->references(LookupContext::canonicalSymbol(symbol), doc, snapshot);
|
NamespaceBindingPtr glo = bind(doc, snapshot);
|
||||||
|
return m_findReferences->references(LookupContext::canonicalSymbol(symbol, glo.data()), doc, snapshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppModelManager::findUsages(CPlusPlus::Symbol *symbol)
|
void CppModelManager::findUsages(CPlusPlus::Symbol *symbol)
|
||||||
|
|||||||
Reference in New Issue
Block a user