diff --git a/src/libs/cplusplus/CppBindings.cpp b/src/libs/cplusplus/CppBindings.cpp deleted file mode 100644 index 25c05e0f48e..00000000000 --- a/src/libs/cplusplus/CppBindings.cpp +++ /dev/null @@ -1,866 +0,0 @@ -/************************************************************************** -** -** 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 "CppBindings.h" -#include "CppDocument.h" -#include "Overview.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -using namespace CPlusPlus; - - -//////////////////////////////////////////////////////////////////////////////// -// Location -//////////////////////////////////////////////////////////////////////////////// -Location::Location() - : _fileId(0), - _sourceLocation(0) -{ } - -Location::Location(Symbol *symbol) - : _fileId(symbol->fileId()), - _sourceLocation(symbol->sourceLocation()) -{ } - -Location::Location(const StringLiteral *fileId, unsigned sourceLocation) - : _fileId(fileId), _sourceLocation(sourceLocation) -{ } - -//////////////////////////////////////////////////////////////////////////////// -// NamespaceBinding -//////////////////////////////////////////////////////////////////////////////// - -NamespaceBinding::NamespaceBinding(NamespaceBinding *parent) - : parent(parent), - anonymousNamespaceBinding(0) -{ - if (parent) - parent->children.append(this); -} - -NamespaceBinding::~NamespaceBinding() -{ - qDeleteAll(QList(children)); - qDeleteAll(QList(classBindings)); - - if (parent) - parent->asNamespaceBinding()->children.removeAll(this); - parent = 0; -} - -const NameId *NamespaceBinding::name() const -{ - if (symbols.size()) { - if (const Name *name = symbols.first()->name()) { - const NameId *nameId = name->asNameId(); - Q_ASSERT(nameId != 0); - - return nameId; - } - } - - return 0; -} - -const Identifier *NamespaceBinding::identifier() const -{ - if (const NameId *nameId = name()) - return nameId->identifier(); - - return 0; -} - -NamespaceBinding *NamespaceBinding::globalNamespaceBinding() -{ - NamespaceBinding *it = this; - - for (; it; it = it->parent) { - if (! it->parent) - break; - } - - return it; -} - -Binding *NamespaceBinding::findClassOrNamespaceBinding(const Identifier *id, QSet *processed) -{ - if (processed->contains(this)) - return 0; - - processed->insert(this); - - if (id->isEqualTo(identifier())) - return const_cast(this); - - foreach (NamespaceBinding *nestedNamespaceBinding, children) { - if (id->isEqualTo(nestedNamespaceBinding->identifier())) - return nestedNamespaceBinding; - } - - foreach (ClassBinding *classBinding, classBindings) { - if (id->isEqualTo(classBinding->identifier())) - return classBinding; - } - - foreach (NamespaceBinding *u, usings) { - if (Binding *b = u->findClassOrNamespaceBinding(id, processed)) - return b; - } - - if (parent) - return parent->findClassOrNamespaceBinding(id, processed); - - return 0; -} - -ClassBinding *NamespaceBinding::findClassBinding(const Name *name, QSet *processed) -{ - if (! name) - return 0; - - if (processed->contains(this)) - return 0; - - if (const QualifiedNameId *q = name->asQualifiedNameId()) { - Binding *current = this; - - for (unsigned i = 0; i < q->nameCount(); ++i) { - const Identifier *nameId = q->nameAt(i)->identifier(); - if (! nameId) - return 0; - - QSet visited; - Binding *binding = current->findClassOrNamespaceBinding(nameId, &visited); // ### TODO: check recursion. - if (! binding) - return 0; - - current = binding; - } - - return current->asClassBinding(); - } - - processed->insert(this); - - const Identifier *id = name->identifier(); - - foreach (ClassBinding *classBinding, classBindings) { - if (id->isEqualTo(classBinding->identifier())) - return classBinding; - } - - if (parent) - return parent->findClassBinding(name, processed); - - foreach (NamespaceBinding *u, usings) { - if (ClassBinding *classBinding = u->findClassBinding(name, processed)) - return classBinding; - } - - return 0; -} - -NamespaceBinding *NamespaceBinding::findNamespaceBinding(const Name *name) -{ - if (! name) - return anonymousNamespaceBinding; - - else if (const NameId *nameId = name->asNameId()) - return findNamespaceBindingForNameId(nameId, /*lookAtParent = */ true); - - else if (const QualifiedNameId *q = name->asQualifiedNameId()) { - NamespaceBinding *current = this; - - for (unsigned i = 0; i < q->nameCount(); ++i) { - const NameId *namespaceName = q->nameAt(i)->asNameId(); - if (! namespaceName) - return 0; - - bool lookAtParent = false; - if (i == 0) - lookAtParent = true; - - NamespaceBinding *binding = current->findNamespaceBindingForNameId(namespaceName, lookAtParent); - if (! binding) - return 0; - - current = binding; - } - - return current; - } - - // invalid binding - return 0; -} - -NamespaceBinding *NamespaceBinding::findNamespaceBindingForNameId(const NameId *name, - bool lookAtParentNamespace) -{ - QSet processed; - return findNamespaceBindingForNameId_helper(name, lookAtParentNamespace, &processed); -} - -NamespaceBinding *NamespaceBinding::findNamespaceBindingForNameId_helper(const NameId *name, - bool lookAtParentNamespace, - QSet *processed) -{ - if (processed->contains(this)) - return 0; - - processed->insert(this); - - foreach (NamespaceBinding *binding, children) { - const Name *bindingName = binding->name(); - - if (! bindingName) - continue; - - if (const NameId *bindingNameId = bindingName->asNameId()) { - if (name->isEqualTo(bindingNameId)) - return binding; - } - } - - foreach (NamespaceBinding *u, usings) { - if (NamespaceBinding *b = u->findNamespaceBindingForNameId_helper(name, lookAtParentNamespace, processed)) { - return b; - } - } - - if (lookAtParentNamespace && parent) - return parent->findNamespaceBindingForNameId_helper(name, lookAtParentNamespace, processed); - - return 0; -} - -NamespaceBinding *NamespaceBinding::findOrCreateNamespaceBinding(Namespace *symbol) -{ - if (NamespaceBinding *binding = findNamespaceBinding(symbol->name())) { - int index = 0; - - for (; index < binding->symbols.size(); ++index) { - Namespace *ns = binding->symbols.at(index); - - if (ns == symbol) - break; - } - - if (index == binding->symbols.size()) - binding->symbols.append(symbol); - - return binding; - } - - NamespaceBinding *binding = new NamespaceBinding(this); - binding->symbols.append(symbol); - - if (! symbol->name()) { - Q_ASSERT(! anonymousNamespaceBinding); - - anonymousNamespaceBinding = binding; - } - - return binding; -} - -static void closure(const Location &loc, - NamespaceBinding *binding, const Name *name, - QList *bindings) -{ - if (bindings->contains(binding)) - return; - - bindings->append(binding); - - Q_ASSERT(name->isNameId()); - - const Identifier *id = name->asNameId()->identifier(); - bool ignoreUsingDirectives = false; - - foreach (Namespace *symbol, binding->symbols) { - Scope *scope = symbol->members(); - - for (Symbol *symbol = scope->lookat(id); symbol; symbol = symbol->next()) { - if (symbol->name() != name || ! symbol->isNamespace()) - continue; - - const Location l(symbol); - - if (l.fileId() == loc.fileId() && l.sourceLocation() < loc.sourceLocation()) { - ignoreUsingDirectives = true; - break; - } - } - } - - if (ignoreUsingDirectives) - return; - - foreach (NamespaceBinding *u, binding->usings) - closure(loc, u, name, bindings); -} - - -NamespaceBinding *NamespaceBinding::resolveNamespace(const Location &loc, - const Name *name, - bool lookAtParent) -{ - if (! name) - return 0; - - else if (const NameId *nameId = name->asNameId()) { - QList bindings; - closure(loc, this, nameId, &bindings); - - QList results; - - foreach (NamespaceBinding *binding, bindings) { - if (NamespaceBinding *b = binding->findNamespaceBinding(nameId)) - results.append(b); - } - - if (results.size() == 1) - return results.at(0); - - else if (results.size() > 1) { - // ### FIXME: return 0; - return results.at(0); - } - - else if (parent && lookAtParent) - return parent->resolveNamespace(loc, name); - - } else if (const QualifiedNameId *q = name->asQualifiedNameId()) { - if (q->nameCount() == 1) { - Q_ASSERT(q->isGlobal()); - - return globalNamespaceBinding()->resolveNamespace(loc, q->nameAt(0)); - } - - NamespaceBinding *current = this; - if (q->isGlobal()) - current = globalNamespaceBinding(); - - current = current->resolveNamespace(loc, q->nameAt(0)); - for (unsigned i = 1; current && i < q->nameCount(); ++i) - current = current->resolveNamespace(loc, q->nameAt(i), false); - - return current; - } - - return 0; -} - -// ### rewrite me -QByteArray NamespaceBinding::qualifiedId() const -{ - if (! parent) - return ""; - - QByteArray s; - - s.append(parent->qualifiedId()); - s.append("::"); - - if (const Identifier *id = identifier()) - s.append(id->chars(), id->size()); - - else - s.append(""); - - return s; -} - -// ### rewrite me -QByteArray ClassBinding::qualifiedId() const -{ - QByteArray s = parent->qualifiedId(); - s += "::"; - - if (const Identifier *id = identifier()) - s.append(id->chars(), id->size()); - - else - s.append(""); - - return s; -} - -Binding *ClassBinding::findClassOrNamespaceBinding(const Identifier *id, QSet *processed) -{ - if (id->isEqualTo(identifier())) - return this; - - if (processed->contains(this)) - return 0; - - processed->insert(this); - - foreach (ClassBinding *nestedClassBinding, children) { - if (id->isEqualTo(nestedClassBinding->identifier())) - return nestedClassBinding; - } - - foreach (ClassBinding *baseClassBinding, baseClassBindings) { - if (! baseClassBinding) - continue; - - else if (Binding *b = baseClassBinding->findClassOrNamespaceBinding(id, processed)) - return b; - } - - if (parent) - return parent->findClassOrNamespaceBinding(id, processed); - - return 0; -} - -ClassBinding *ClassBinding::findClassBinding(const Name *name, QSet *processed) -{ - if (! name) - return 0; - - if (processed->contains(this)) - return 0; - - processed->insert(this); - - if (const QualifiedNameId *q = name->asQualifiedNameId()) { - Binding *currentBinding = this; - - for (unsigned i = 0; i < q->nameCount() - 1; ++i) { - const Identifier *id = q->nameAt(i)->identifier(); - if (! id) - return 0; - - Binding *classOrNamespaceBinding = currentBinding->findClassOrNamespaceBinding(id, processed); - - if (! classOrNamespaceBinding) - return 0; - - currentBinding = classOrNamespaceBinding; - } - - if (currentBinding) - return currentBinding->findClassBinding(q->unqualifiedNameId(), processed); - - return 0; - } - - if (const Identifier *id = name->identifier()) { - if (id->isEqualTo(identifier())) - return this; - - foreach (ClassBinding *nestedClassBinding, children) { - if (const Identifier *nestedClassId = nestedClassBinding->identifier()) { - if (nestedClassId->isEqualTo(id)) - return nestedClassBinding; - } - } - - if (parent) - return parent->findClassBinding(name, processed); - } - - return 0; -} - -static int depth; - -void NamespaceBinding::dump() -{ - qDebug() << QByteArray(depth, ' ').constData() << "namespace" << qualifiedId().constData() - << " # " << symbols.size(); - - ++depth; - - foreach (ClassBinding *classBinding, classBindings) { - classBinding->dump(); - } - - foreach (NamespaceBinding *child, children) { - child->dump(); - } - - --depth; -} - -void ClassBinding::dump() -{ - qDebug() << QByteArray(depth, ' ').constData() << "class" << qualifiedId().constData() - << " # " << symbols.size(); - - ++depth; - - foreach (ClassBinding *classBinding, children) { - classBinding->dump(); - } - - --depth; -} - -//////////////////////////////////////////////////////////////////////////////// -// ClassBinding -//////////////////////////////////////////////////////////////////////////////// -ClassBinding::ClassBinding(NamespaceBinding *parent) - : parent(parent) -{ - parent->classBindings.append(this); -} - -ClassBinding::ClassBinding(ClassBinding *parentClass) - : parent(parentClass) -{ - parentClass->children.append(this); -} - -ClassBinding::~ClassBinding() -{ - qDeleteAll(QList(children)); - if (NamespaceBinding *nsBinding = parent->asNamespaceBinding()) - nsBinding->classBindings.removeAll(this); - if (ClassBinding *classBinding = parent->asClassBinding()) - classBinding->children.removeAll(this); - parent = 0; -} - -const Name *ClassBinding::name() const -{ - if (symbols.isEmpty()) - return 0; - - return symbols.first()->name(); -} - -const Identifier *ClassBinding::identifier() const -{ - if (const Name *n = name()) - return n->identifier(); - - return 0; -} - -namespace { - -//////////////////////////////////////////////////////////////////////////////// -// Binder -//////////////////////////////////////////////////////////////////////////////// - -class Binder: protected SymbolVisitor -{ -public: - Binder(NamespaceBinding *globals); - virtual ~Binder(); - - NamespaceBinding *operator()(Document::Ptr doc, const Snapshot &snapshot) - { - namespaceBinding = _globals; - const Snapshot previousSnapshot = _snapshot; - - _snapshot = snapshot; - (void) bind(doc); - _snapshot = previousSnapshot; - - return _globals; - } - - Snapshot _snapshot; - -protected: - NamespaceBinding *bind(Document::Ptr doc) - { - QSet processed; - return bind(doc, &processed); - } - - NamespaceBinding *bind(Document::Ptr doc, QSet *processed) - { - if (processed->contains(doc->fileName())) - return 0; - - processed->insert(doc->fileName()); - - foreach (const Document::Include &i, doc->includes()) { - if (Document::Ptr includedDoc = _snapshot.document(i.fileName())) { - /*NamepaceBinding *binding = */ bind(includedDoc, processed); - } - } - - Namespace *ns = doc->globalNamespace(); - _globals->symbols.append(ns); - - for (unsigned i = 0; i < ns->memberCount(); ++i) { - (void) bind(ns->memberAt(i), _globals); - } - - return _globals; - } - - NamespaceBinding *bind(Symbol *symbol, NamespaceBinding *binding); - NamespaceBinding *findOrCreateNamespaceBinding(Namespace *symbol); - NamespaceBinding *resolveNamespace(const Location &loc, const Name *name); - - NamespaceBinding *switchNamespaceBinding(NamespaceBinding *binding); - - ClassBinding *findOrCreateClassBinding(Class *classSymbol); - ClassBinding *findClassBinding(const Name *name); - - ClassBinding *switchClassBinding(ClassBinding *binding); - - using SymbolVisitor::visit; - - virtual bool visit(Namespace *); - virtual bool visit(UsingNamespaceDirective *); - virtual bool visit(Class *); - virtual bool visit(Function *); - virtual bool visit(Block *); - -private: - NamespaceBinding *_globals; - NamespaceBinding *namespaceBinding; - ClassBinding *classBinding; -}; - -Binder::Binder(NamespaceBinding *globals) - : _globals(globals), - namespaceBinding(0), - classBinding(0) -{ } - -Binder::~Binder() -{ } - -NamespaceBinding *Binder::bind(Symbol *symbol, NamespaceBinding *binding) -{ - NamespaceBinding *previousBinding = switchNamespaceBinding(binding); - accept(symbol); - return switchNamespaceBinding(previousBinding); -} - -NamespaceBinding *Binder::findOrCreateNamespaceBinding(Namespace *symbol) -{ return namespaceBinding->findOrCreateNamespaceBinding(symbol); } - -NamespaceBinding *Binder::resolveNamespace(const Location &loc, const Name *name) -{ - if (! namespaceBinding) - return 0; - - return namespaceBinding->resolveNamespace(loc, name); -} - -NamespaceBinding *Binder::switchNamespaceBinding(NamespaceBinding *binding) -{ - NamespaceBinding *previousBinding = namespaceBinding; - namespaceBinding = binding; - return previousBinding; -} - -ClassBinding *Binder::findOrCreateClassBinding(Class *classSymbol) -{ - // ### FINISH ME - ClassBinding *binding = 0; - - if (classBinding) - binding = new ClassBinding(classBinding); - else - binding = new ClassBinding(namespaceBinding); - - binding->symbols.append(classSymbol); - return binding; -} - -ClassBinding *Binder::findClassBinding(const Name *name) -{ - QSet processed; - - if (classBinding) { - if (ClassBinding *k = classBinding->findClassBinding(name, &processed)) - return k; - - processed.clear(); - } - - if (namespaceBinding) - return namespaceBinding->findClassBinding(name, &processed); - - return 0; -} - -ClassBinding *Binder::switchClassBinding(ClassBinding *binding) -{ - ClassBinding *previousClassBinding = classBinding; - classBinding = binding; - return previousClassBinding; -} - -bool Binder::visit(Namespace *symbol) -{ - NamespaceBinding *binding = findOrCreateNamespaceBinding(symbol); - - for (unsigned i = 0; i < symbol->memberCount(); ++i) { - Symbol *member = symbol->memberAt(i); - - bind(member, binding); - } - - return false; -} - -bool Binder::visit(UsingNamespaceDirective *u) -{ - NamespaceBinding *resolved = resolveNamespace(Location(u), u->name()); - - if (! resolved) - return false; - - namespaceBinding->usings.append(resolved); - - return false; -} - -bool Binder::visit(Class *classSymbol) -{ - ClassBinding *binding = findOrCreateClassBinding(classSymbol); - ClassBinding *previousClassBinding = switchClassBinding(binding); - - for (unsigned i = 0; i < classSymbol->baseClassCount(); ++i) { - BaseClass *baseClass = classSymbol->baseClassAt(i); - ClassBinding *baseClassBinding = findClassBinding(baseClass->name()); - binding->baseClassBindings.append(baseClassBinding); - } - - for (unsigned i = 0; i < classSymbol->memberCount(); ++i) - accept(classSymbol->memberAt(i)); - - (void) switchClassBinding(previousClassBinding); - - return false; -} - -bool Binder::visit(Function *) -{ return false; } - -bool Binder::visit(Block *) -{ return false; } - -} // end of anonymous namespace - -static NamespaceBinding *find_helper(Namespace *symbol, NamespaceBinding *binding, - QSet *processed) -{ - if (binding && ! processed->contains(binding)) { - processed->insert(binding); - - if (binding->symbols.contains(symbol)) - return binding; - - foreach (NamespaceBinding *nestedBinding, binding->children) { - if (NamespaceBinding *ns = find_helper(symbol, nestedBinding, processed)) - return ns; - } - - if (NamespaceBinding *a = find_helper(symbol, binding->anonymousNamespaceBinding, processed)) - return a; - } - - return 0; -} - -static ClassBinding *find_helper(Class *symbol, Binding *binding, - QSet *processed) -{ - if (binding && ! processed->contains(binding)) { - processed->insert(binding); - - if (NamespaceBinding *namespaceBinding = binding->asNamespaceBinding()) { - foreach (ClassBinding *classBinding, namespaceBinding->classBindings) { - if (ClassBinding *c = find_helper(symbol, classBinding, processed)) - return c; - } - - foreach (NamespaceBinding *nestedBinding, namespaceBinding->children) { - if (ClassBinding *c = find_helper(symbol, nestedBinding, processed)) - return c; - } - - if (ClassBinding *a = find_helper(symbol, namespaceBinding->anonymousNamespaceBinding, processed)) - return a; - - } else if (ClassBinding *classBinding = binding->asClassBinding()) { - foreach (Class *klass, classBinding->symbols) { - if (klass == symbol) - return classBinding; - } - - foreach (ClassBinding *nestedClassBinding, classBinding->children) { - if (ClassBinding *c = find_helper(symbol, nestedClassBinding, processed)) - return c; - } - -#if 0 // ### FIXME - if (ClassBinding *a = find_helper(symbol, classBinding->anonymousClassBinding, processed)) - return a; -#endif - } - } - - return 0; -} - -NamespaceBinding *NamespaceBinding::find(Namespace *symbol, NamespaceBinding *binding) -{ - QSet processed; - return find_helper(symbol, binding, &processed); -} - -ClassBinding *NamespaceBinding::find(Class *symbol, NamespaceBinding *binding) -{ - QSet processed; - return find_helper(symbol, binding, &processed); -} - -NamespaceBindingPtr CPlusPlus::bind(Document::Ptr doc, Snapshot snapshot) -{ - NamespaceBindingPtr global(new NamespaceBinding()); - - Binder bind(global.data()); - bind(doc, snapshot); - return global; -} - diff --git a/src/libs/cplusplus/CppBindings.h b/src/libs/cplusplus/CppBindings.h deleted file mode 100644 index d4f7380be73..00000000000 --- a/src/libs/cplusplus/CppBindings.h +++ /dev/null @@ -1,195 +0,0 @@ -/************************************************************************** -** -** 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. -** -**************************************************************************/ - -#ifndef CPPBINDINGS_H -#define CPPBINDINGS_H - -#include "CppDocument.h" - -#include -#include -#include -#include - -namespace CPlusPlus { - -class Location; -class Binding; -class NamespaceBinding; -class ClassBinding; - -typedef QSharedPointer BindingPtr; -typedef QSharedPointer ClassBindingPtr; -typedef QSharedPointer NamespaceBindingPtr; - -class CPLUSPLUS_EXPORT Location -{ -public: - Location(); - Location(Symbol *symbol); - Location(const StringLiteral *fileId, unsigned sourceLocation); - - inline bool isValid() const - { return _fileId != 0; } - - inline operator bool() const - { return _fileId != 0; } - - inline const StringLiteral *fileId() const - { return _fileId; } - - inline unsigned sourceLocation() const - { return _sourceLocation; } - -private: - const StringLiteral *_fileId; - unsigned _sourceLocation; -}; - -class CPLUSPLUS_EXPORT Binding -{ - Q_DISABLE_COPY(Binding) - -public: - Binding() {} - virtual ~Binding() {} - - virtual QByteArray qualifiedId() const = 0; - virtual NamespaceBinding *asNamespaceBinding() { return 0; } - virtual ClassBinding *asClassBinding() { return 0; } - - virtual ClassBinding *findClassBinding(const Name *name, QSet *processed) = 0; - virtual Binding *findClassOrNamespaceBinding(const Identifier *id, QSet *processed) = 0; -}; - -class CPLUSPLUS_EXPORT NamespaceBinding: public Binding -{ -public: - /// Constructs a binding with the given parent. - NamespaceBinding(NamespaceBinding *parent = 0); - - /// Destroys the binding. - virtual ~NamespaceBinding(); - - /// Returns this binding's name. - const NameId *name() const; - - /// Returns this binding's identifier. - const Identifier *identifier() const; - - /// Returns the binding for the global namespace (aka ::). - NamespaceBinding *globalNamespaceBinding(); - - /// Returns the binding for the given namespace symbol. - NamespaceBinding *findNamespaceBinding(const Name *name); - - /// Returns the binding associated with the given symbol. - NamespaceBinding *findOrCreateNamespaceBinding(Namespace *symbol); - - NamespaceBinding *resolveNamespace(const Location &loc, - const Name *name, - bool lookAtParent = true); - - virtual ClassBinding *findClassBinding(const Name *name, QSet *processed); - virtual Binding *findClassOrNamespaceBinding(const Identifier *id, QSet *processed); - - /// Helpers. - virtual QByteArray qualifiedId() const; - void dump(); - - virtual NamespaceBinding *asNamespaceBinding() { return this; } - - static NamespaceBinding *find(Namespace *symbol, NamespaceBinding *binding); - static ClassBinding *find(Class *symbol, NamespaceBinding *binding); - -private: - NamespaceBinding *findNamespaceBindingForNameId(const NameId *name, - bool lookAtParentNamespace); - - NamespaceBinding *findNamespaceBindingForNameId_helper(const NameId *name, - bool lookAtParentNamespace, - QSet *processed); - -public: // attributes - /// This binding's parent. - NamespaceBinding *parent; - - /// Binding for anonymous namespace symbols. - NamespaceBinding *anonymousNamespaceBinding; - - /// This binding's connections. - QList children; - - /// This binding's list of using namespaces. - QList usings; - - /// This binding's namespace symbols. - QList symbols; - - QList classBindings; -}; - -class CPLUSPLUS_EXPORT ClassBinding: public Binding -{ -public: - ClassBinding(NamespaceBinding *parent); - ClassBinding(ClassBinding *parentClass); - virtual ~ClassBinding(); - - virtual ClassBinding *asClassBinding() { return this; } - - /// Returns this binding's name. - const Name *name() const; - - /// Returns this binding's identifier. - const Identifier *identifier() const; - virtual QByteArray qualifiedId() const; - - virtual ClassBinding *findClassBinding(const Name *name, QSet *processed); - virtual Binding *findClassOrNamespaceBinding(const Identifier *id, QSet *processed); - - void dump(); - -public: // attributes - Binding *parent; - - QList children; - - /// This binding's class symbols. - QList symbols; - - /// Bindings for the base classes. - QList baseClassBindings; -}; - -CPLUSPLUS_EXPORT NamespaceBindingPtr bind(Document::Ptr doc, Snapshot snapshot); - -} // end of namespace CPlusPlus - -#endif // CPPBINDINGS_H diff --git a/src/libs/cplusplus/DeprecatedLookupContext.cpp b/src/libs/cplusplus/DeprecatedLookupContext.cpp index 75c71c30a1e..85220efaadb 100644 --- a/src/libs/cplusplus/DeprecatedLookupContext.cpp +++ b/src/libs/cplusplus/DeprecatedLookupContext.cpp @@ -30,7 +30,6 @@ #include "DeprecatedLookupContext.h" #include "ResolveExpression.h" #include "Overview.h" -#include "CppBindings.h" #include #include @@ -623,142 +622,3 @@ void DeprecatedLookupContext::expand(Scope *scope, expandObjCClass(objcKlass, visibleScopes, expandedScopes); } } - -static void visibleClassBindings_helper(ClassBinding *classBinding, - QList *allClassBindings, - QSet *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 visibleClassBindings(Symbol *symbol, NamespaceBinding *globalNamespace) -{ - QList classBindings; - - if (! symbol) - return classBindings; - - else if (Class *klass = symbol->asClass()) { - QSet processed; - - visibleClassBindings_helper(NamespaceBinding::find(klass, globalNamespace), - &classBindings, &processed); - } - - return classBindings; -} - -Symbol *DeprecatedLookupContext::canonicalSymbol(Symbol *symbol, - NamespaceBinding *globalNamespace) -{ - Symbol *canonicalSymbol = DeprecatedLookupContext::canonicalSymbol(symbol); - if (! canonicalSymbol) - return 0; - - if (const Identifier *symbolId = canonicalSymbol->identifier()) { - if (symbolId && canonicalSymbol->type()->isFunctionType()) { - Class *enclosingClass = canonicalSymbol->scope()->owner()->asClass(); - const QList 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 DeprecatedLookupContext::canonicalSymbol(f); - } - } - } - } - } - } - - return canonicalSymbol; -} - -Symbol *DeprecatedLookupContext::canonicalSymbol(const QList &candidates, - NamespaceBinding *globalNamespaceBinding) -{ - if (candidates.isEmpty()) - return 0; - - return canonicalSymbol(candidates.first(), globalNamespaceBinding); -} - -Symbol *DeprecatedLookupContext::canonicalSymbol(const QList &results, - NamespaceBinding *globalNamespaceBinding) -{ - QList candidates; - - foreach (const LookupItem &result, results) - candidates.append(result.declaration()); // ### not exactly. - - return canonicalSymbol(candidates, globalNamespaceBinding); -} - - -Symbol *DeprecatedLookupContext::canonicalSymbol(Symbol *symbol) -{ - Symbol *canonical = symbol; - Class *canonicalClass = 0; - ObjCClass *canonicalObjCClass = 0; - ObjCProtocol *canonicalObjCProto = 0; - - for (; symbol; symbol = symbol->next()) { - if (symbol->identifier() == canonical->identifier()) { - canonical = symbol; - - if (Class *klass = symbol->asClass()) - canonicalClass = klass; - else if (ObjCClass *clazz = symbol->asObjCClass()) - canonicalObjCClass = clazz; - else if (ObjCProtocol *proto = symbol->asObjCProtocol()) - canonicalObjCProto = proto; - } - } - - if (canonicalClass) { - Q_ASSERT(canonical != 0); - - if (canonical->isForwardClassDeclaration()) - return canonicalClass; // prefer class declarations when available. - } else if (canonicalObjCClass) { - Q_ASSERT(canonical != 0); - - if (canonical->isObjCForwardClassDeclaration()) - return canonicalObjCClass; - } else if (canonicalObjCProto) { - Q_ASSERT(canonical != 0); - - if (canonical->isObjCForwardProtocolDeclaration()) - return canonicalObjCProto; - } - - if (canonical && canonical->scope()->isClassScope()) { - Class *enclosingClass = canonical->scope()->owner()->asClass(); - - if (enclosingClass->identifier() == canonical->identifier()) - return enclosingClass; - } - - return canonical; -} diff --git a/src/libs/cplusplus/DeprecatedLookupContext.h b/src/libs/cplusplus/DeprecatedLookupContext.h index 19d63e3c98e..24df9839a0d 100644 --- a/src/libs/cplusplus/DeprecatedLookupContext.h +++ b/src/libs/cplusplus/DeprecatedLookupContext.h @@ -57,15 +57,6 @@ public: Document::Ptr document(const QString &fileName) const; Snapshot snapshot() const; - static Symbol *canonicalSymbol(const QList &candidates, - NamespaceBinding *globalNamespaceBinding); - - static Symbol *canonicalSymbol(Symbol *symbol, - NamespaceBinding *globalNamespaceBinding); - - static Symbol *canonicalSymbol(const QList &candidates, - NamespaceBinding *globalNamespaceBinding); - QList resolve(const Name *name) const { return resolve(name, visibleScopes()); } @@ -157,7 +148,6 @@ public: QList *expandedScopes) const; private: - static Symbol *canonicalSymbol(Symbol *symbol); QList resolveQualifiedNameId(const QualifiedNameId *q, const QList &visibleScopes, diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp index 003e4df8404..ddfd16bc3b6 100644 --- a/src/libs/cplusplus/FindUsages.cpp +++ b/src/libs/cplusplus/FindUsages.cpp @@ -39,6 +39,7 @@ #include #include +#include using namespace CPlusPlus; @@ -56,11 +57,6 @@ FindUsages::FindUsages(Document::Ptr doc, const Snapshot &snapshot) typeofExpression.init(_doc, _snapshot, _context.bindings()); } -void FindUsages::setGlobalNamespaceBinding(NamespaceBindingPtr globalNamespaceBinding) -{ - _globalNamespaceBinding = globalNamespaceBinding; -} - QList FindUsages::usages() const { return _usages; } @@ -153,61 +149,12 @@ void FindUsages::reportResult(unsigned tokenIndex) bool FindUsages::checkCandidates(const QList &candidates) const { - if (Symbol *canonicalSymbol = DeprecatedLookupContext::canonicalSymbol(candidates, _globalNamespaceBinding.data())) { - -#if 0 - Symbol *c = candidates.first(); - qDebug() << "*** canonical symbol:" << canonicalSymbol->fileName() - << canonicalSymbol->line() << canonicalSymbol->column() - << "candidates:" << candidates.size() - << c->fileName() << c->line() << c->column(); -#endif - - return checkSymbol(canonicalSymbol); - } - - return false; -} - -bool FindUsages::checkScope(Symbol *symbol, Symbol *otherSymbol) const -{ - if (! (symbol && otherSymbol)) - return false; - - else if (symbol->scope() == otherSymbol->scope()) - return true; - - else if (symbol->name() && otherSymbol->name()) { - - if (! symbol->name()->isEqualTo(otherSymbol->name())) - return false; - - } else if (symbol->name() != otherSymbol->name()) { - return false; - } - - return checkScope(symbol->enclosingSymbol(), otherSymbol->enclosingSymbol()); -} - -bool FindUsages::checkSymbol(Symbol *symbol) const -{ - if (! symbol) { - return false; - - } else if (symbol == _declSymbol) { - return true; - - } else if (symbol->line() == _declSymbol->line() && symbol->column() == _declSymbol->column()) { - if (! qstrcmp(symbol->fileName(), _declSymbol->fileName())) - return true; - - } else if (symbol->isForwardClassDeclaration() && (_declSymbol->isClass() || - _declSymbol->isForwardClassDeclaration())) { - return checkScope(symbol, _declSymbol); - - } else if (_declSymbol->isForwardClassDeclaration() && (symbol->isClass() || - symbol->isForwardClassDeclaration())) { - return checkScope(symbol, _declSymbol); + if (ClassOrNamespace *c = _context.lookupType(_declSymbol)) { + for (int i = candidates.size() - 1; i != -1; --i) { + Symbol *s = candidates.at(i); + if (_context.lookupType(s) == c) + return true; + } } return false; diff --git a/src/libs/cplusplus/FindUsages.h b/src/libs/cplusplus/FindUsages.h index 97729fd49ab..efc0775030d 100644 --- a/src/libs/cplusplus/FindUsages.h +++ b/src/libs/cplusplus/FindUsages.h @@ -32,7 +32,6 @@ #include "LookupContext.h" #include "CppDocument.h" -#include "CppBindings.h" #include "Semantic.h" #include "TypeOfExpression.h" #include @@ -62,8 +61,6 @@ class CPLUSPLUS_EXPORT FindUsages: protected ASTVisitor public: FindUsages(Document::Ptr doc, const Snapshot &snapshot); - void setGlobalNamespaceBinding(NamespaceBindingPtr globalNamespaceBinding); - void operator()(Symbol *symbol); QList usages() const; @@ -79,9 +76,7 @@ protected: void reportResult(unsigned tokenIndex, const QList &candidates); void reportResult(unsigned tokenIndex); - bool checkSymbol(Symbol *symbol) const; bool checkCandidates(const QList &candidates) const; - bool checkScope(Symbol *symbol, Symbol *otherSymbol) const; void checkExpression(unsigned startToken, unsigned endToken); void ensureNameIsValid(NameAST *ast); @@ -112,7 +107,6 @@ private: QByteArray _source; Document::Ptr _exprDoc; Semantic _sem; - NamespaceBindingPtr _globalNamespaceBinding; QList _postfixExpressionStack; QList _qualifiedNameStack; QList _references; diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index ed61e1f8da6..4aada73f93a 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -30,7 +30,6 @@ #include "LookupContext.h" #include "ResolveExpression.h" #include "Overview.h" -#include "CppBindings.h" #include "DeprecatedGenTemplateInstance.h" #include @@ -186,10 +185,8 @@ QList LookupContext::lookup(const Name *name, Scope *scope) const if (! name) return candidates; - const Identifier *id = name->identifier(); - for (; scope; scope = scope->enclosingScope()) { - if (id && scope->isBlockScope()) { + if ((name->isNameId() || name->isTemplateNameId()) && scope->isBlockScope()) { bindings()->lookupInScope(name, scope, &candidates, /*templateId = */ 0); if (! candidates.isEmpty()) diff --git a/src/libs/cplusplus/cplusplus-lib.pri b/src/libs/cplusplus/cplusplus-lib.pri index 07bf9493419..6cd7057716f 100644 --- a/src/libs/cplusplus/cplusplus-lib.pri +++ b/src/libs/cplusplus/cplusplus-lib.pri @@ -37,7 +37,6 @@ HEADERS += \ $$PWD/LookupItem.h \ $$PWD/LookupContext.h \ $$PWD/DeprecatedLookupContext.h \ - $$PWD/CppBindings.h \ $$PWD/ASTParent.h \ $$PWD/DeprecatedGenTemplateInstance.h \ $$PWD/FindUsages.h \ @@ -64,7 +63,6 @@ SOURCES += \ $$PWD/LookupItem.cpp \ $$PWD/LookupContext.cpp \ $$PWD/DeprecatedLookupContext.cpp \ - $$PWD/CppBindings.cpp \ $$PWD/ASTParent.cpp \ $$PWD/DeprecatedGenTemplateInstance.cpp \ $$PWD/FindUsages.cpp \ diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index ac8851de7bf..7924be1b5dd 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -48,7 +48,6 @@ #include #include #include -#include #include #include #include @@ -56,7 +55,6 @@ #include #include #include -#include #include #include @@ -846,13 +844,17 @@ CPlusPlus::Symbol *CPPEditor::findCanonicalSymbol(const QTextCursor &cursor, TypeOfExpression typeOfExpression; typeOfExpression.init(doc, snapshot); - const QList results = typeOfExpression(code, doc->scopeAt(line, col), - TypeOfExpression::Preprocess); + Scope *scope = doc->scopeAt(line, col); - NamespaceBindingPtr glo = bind(doc, snapshot); - Symbol *canonicalSymbol = DeprecatedLookupContext::canonicalSymbol(results, glo.data()); + const QList results = typeOfExpression(code, scope, TypeOfExpression::Preprocess); + for (int i = results.size() - 1; i != -1; --i) { // ### TODO virtual methods and classes. + const LookupItem &r = results.at(i); - return canonicalSymbol; + if (r.declaration()) + return r.declaration(); + } + + return 0; } const Macro *CPPEditor::findCanonicalMacro(const QTextCursor &cursor, @@ -934,13 +936,13 @@ void CPPEditor::renameUsagesNow() Symbol *CPPEditor::markSymbols() { - updateSemanticInfo(m_semanticHighlighter->semanticInfo(currentSource())); + //updateSemanticInfo(m_semanticHighlighter->semanticInfo(currentSource())); abortRename(); QList selections; - SemanticInfo info = m_lastSemanticInfo; + const SemanticInfo info = m_lastSemanticInfo; Symbol *canonicalSymbol = findCanonicalSymbol(textCursor(), info.doc, info.snapshot); if (canonicalSymbol) { @@ -1916,7 +1918,11 @@ void CPPEditor::updateSemanticInfo(const SemanticInfo &semanticInfo) } setExtraSelections(UnusedSymbolSelection, unusedSelections); - setExtraSelections(CodeSemanticsSelection, m_renameSelections); // ### + + if (! m_renameSelections.isEmpty()) + setExtraSelections(CodeSemanticsSelection, m_renameSelections); // ### + else + markSymbols(); m_lastSemanticInfo.forced = false; // clear the forced flag } diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index 6a6a048da72..1238581af19 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -51,7 +51,6 @@ #include #include -#include #include #include @@ -120,8 +119,6 @@ public: doc->check(); FindUsages process(doc, snapshot); - process.setGlobalNamespaceBinding(bind(doc, snapshot)); - process(symbol); usages = process.usages(); } @@ -177,7 +174,6 @@ QList CppFindReferences::references(Symbol *symbol, QList references; FindUsages findUsages(doc, snapshot); - findUsages.setGlobalNamespaceBinding(bind(doc, snapshot)); findUsages(symbol); references = findUsages.references(); diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 351364eb27e..b7c2a6a678d 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -791,8 +791,7 @@ QList CppModelManager::references(CPlusPlus::Symbol *symbol, CPlusPlus::Document::Ptr doc, const CPlusPlus::Snapshot &snapshot) { - NamespaceBindingPtr glo = bind(doc, snapshot); - return m_findReferences->references(DeprecatedLookupContext::canonicalSymbol(symbol, glo.data()), doc, snapshot); + return m_findReferences->references(symbol, doc, snapshot); } void CppModelManager::findUsages(CPlusPlus::Document::Ptr symbolDocument, CPlusPlus::Symbol *symbol)