forked from qt-creator/qt-creator
Ported completeScope(), completeNamespace() and completeClass() to use the new LookupContext.
This commit is contained in:
@@ -138,6 +138,16 @@ ClassOrNamespace *LookupContext::classOrNamespace(Symbol *symbol) const
|
||||
return bindings()->findClassOrNamespace(symbol);
|
||||
}
|
||||
|
||||
ClassOrNamespace *LookupContext::classOrNamespace(const Name *name, Symbol *lastVisibleSymbol) const
|
||||
{
|
||||
Scope *scope = _thisDocument->globalSymbols();
|
||||
|
||||
if (lastVisibleSymbol && lastVisibleSymbol->scope())
|
||||
scope = lastVisibleSymbol->scope();
|
||||
|
||||
return classOrNamespace(name, lastVisibleSymbol);
|
||||
}
|
||||
|
||||
QList<Symbol *> LookupContext::lookup(const Name *name, Scope *scope) const
|
||||
{
|
||||
QList<Symbol *> candidates;
|
||||
|
||||
@@ -178,6 +178,7 @@ public:
|
||||
|
||||
ClassOrNamespace *globalNamespace() const;
|
||||
|
||||
ClassOrNamespace *classOrNamespace(const Name *name, Symbol *lastVisibleSymbol) const;
|
||||
ClassOrNamespace *classOrNamespace(const Name *name, Scope *scope) const;
|
||||
ClassOrNamespace *classOrNamespace(Symbol *symbol) const;
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include <cplusplus/ExpressionUnderCursor.h>
|
||||
#include <cplusplus/BackwardsScanner.h>
|
||||
#include <cplusplus/TokenUnderCursor.h>
|
||||
#include <cplusplus/LookupContext.h>
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/mimedatabase.h>
|
||||
@@ -1149,26 +1150,42 @@ bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults,
|
||||
}
|
||||
|
||||
bool CppCodeCompletion::completeScope(const QList<LookupItem> &results,
|
||||
const DeprecatedLookupContext &context)
|
||||
const DeprecatedLookupContext &deprecatedContext)
|
||||
{
|
||||
QList<Symbol *> classes, namespaces;
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
if (results.isEmpty())
|
||||
return false;
|
||||
|
||||
LookupContext context(deprecatedContext.expressionDocument(),
|
||||
deprecatedContext.thisDocument(),
|
||||
deprecatedContext.snapshot());
|
||||
|
||||
foreach (const LookupItem &result, results) {
|
||||
FullySpecifiedType ty = result.type();
|
||||
Symbol *lastVisibleSymbol = result.lastVisibleSymbol();
|
||||
|
||||
if (Class *classTy = ty->asClassType())
|
||||
classes.append(classTy);
|
||||
if (NamedType *namedTy = ty->asNamedType()) {
|
||||
if (ClassOrNamespace *b = context.classOrNamespace(namedTy->name(), lastVisibleSymbol)) {
|
||||
completeClass(b, context);
|
||||
break;
|
||||
}
|
||||
|
||||
else if (Namespace *namespaceTy = ty->asNamespaceType())
|
||||
namespaces.append(namespaceTy);
|
||||
} else if (Class *classTy = ty->asClassType()) {
|
||||
if (ClassOrNamespace *b = context.classOrNamespace(classTy)) {
|
||||
completeClass(b, context);
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (Namespace *nsTy = ty->asNamespaceType()) {
|
||||
if (ClassOrNamespace *b = context.classOrNamespace(nsTy)) {
|
||||
completeNamespace(b, context);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (! classes.isEmpty())
|
||||
completeClass(classes, context);
|
||||
|
||||
else if (! namespaces.isEmpty() && m_completions.isEmpty())
|
||||
completeNamespace(namespaces, context);
|
||||
|
||||
return ! m_completions.isEmpty();
|
||||
}
|
||||
|
||||
@@ -1295,58 +1312,124 @@ bool CppCodeCompletion::completeInclude(const QTextCursor &cursor)
|
||||
return !m_completions.isEmpty();
|
||||
}
|
||||
|
||||
void CppCodeCompletion::completeNamespace(const QList<Symbol *> &candidates,
|
||||
const DeprecatedLookupContext &context)
|
||||
void CppCodeCompletion::completeNamespace(ClassOrNamespace *b, const LookupContext &)
|
||||
{
|
||||
QList<Scope *> todo;
|
||||
QList<Scope *> visibleScopes = context.visibleScopes();
|
||||
foreach (Symbol *candidate, candidates) {
|
||||
if (Namespace *ns = candidate->asNamespace())
|
||||
context.expand(ns->members(), visibleScopes, &todo);
|
||||
}
|
||||
QSet<ClassOrNamespace *> bindingsVisited;
|
||||
QList<ClassOrNamespace *> bindingsToVisit;
|
||||
bindingsToVisit.append(b);
|
||||
|
||||
foreach (Scope *scope, todo) {
|
||||
if (! (scope->isNamespaceScope() || scope->isEnumScope()))
|
||||
while (! bindingsToVisit.isEmpty()) {
|
||||
ClassOrNamespace *binding = bindingsToVisit.takeFirst();
|
||||
if (! binding || bindingsVisited.contains(binding))
|
||||
continue;
|
||||
|
||||
addCompletionItem(scope->owner());
|
||||
bindingsVisited.insert(binding);
|
||||
bindingsToVisit += binding->usings();
|
||||
|
||||
for (unsigned i = 0; i < scope->symbolCount(); ++i) {
|
||||
addCompletionItem(scope->symbolAt(i));
|
||||
QList<Scope *> scopesToVisit;
|
||||
QSet<Scope *> scopesVisited;
|
||||
|
||||
foreach (Symbol *bb, binding->symbols()) {
|
||||
if (Namespace *ns = bb->asNamespace())
|
||||
scopesToVisit.append(ns->members());
|
||||
}
|
||||
|
||||
foreach (Enum *e, binding->enums()) {
|
||||
scopesToVisit.append(e->members());
|
||||
}
|
||||
|
||||
while (! scopesToVisit.isEmpty()) {
|
||||
Scope *scope = scopesToVisit.takeFirst();
|
||||
if (! scope || scopesVisited.contains(scope))
|
||||
continue;
|
||||
|
||||
scopesVisited.insert(scope);
|
||||
|
||||
for (Scope::iterator it = scope->firstSymbol(); it != scope->lastSymbol(); ++it) {
|
||||
Symbol *member = *it;
|
||||
addCompletionItem(member);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CppCodeCompletion::completeNamespace(const QList<Symbol *> &candidates,
|
||||
const DeprecatedLookupContext &deprecatedContext)
|
||||
{
|
||||
if (candidates.isEmpty())
|
||||
return;
|
||||
|
||||
else if (Namespace *ns = candidates.first()->asNamespace()) {
|
||||
LookupContext context(deprecatedContext.expressionDocument(),
|
||||
deprecatedContext.thisDocument(),
|
||||
deprecatedContext.snapshot());
|
||||
|
||||
if (ClassOrNamespace *binding = context.classOrNamespace(ns))
|
||||
completeNamespace(binding, context);
|
||||
}
|
||||
}
|
||||
|
||||
void CppCodeCompletion::completeClass(ClassOrNamespace *b, const LookupContext &, bool staticLookup)
|
||||
{
|
||||
QSet<ClassOrNamespace *> bindingsVisited;
|
||||
QList<ClassOrNamespace *> bindingsToVisit;
|
||||
bindingsToVisit.append(b);
|
||||
|
||||
while (! bindingsToVisit.isEmpty()) {
|
||||
ClassOrNamespace *binding = bindingsToVisit.takeFirst();
|
||||
if (! binding || bindingsVisited.contains(binding))
|
||||
continue;
|
||||
|
||||
bindingsVisited.insert(binding);
|
||||
bindingsToVisit += binding->usings();
|
||||
|
||||
QList<Scope *> scopesToVisit;
|
||||
QSet<Scope *> scopesVisited;
|
||||
|
||||
foreach (Symbol *bb, binding->symbols()) {
|
||||
if (Class *k = bb->asClass())
|
||||
scopesToVisit.append(k->members());
|
||||
}
|
||||
|
||||
foreach (Enum *e, binding->enums())
|
||||
scopesToVisit.append(e->members());
|
||||
|
||||
while (! scopesToVisit.isEmpty()) {
|
||||
Scope *scope = scopesToVisit.takeFirst();
|
||||
if (! scope || scopesVisited.contains(scope))
|
||||
continue;
|
||||
|
||||
scopesVisited.insert(scope);
|
||||
|
||||
for (Scope::iterator it = scope->firstSymbol(); it != scope->lastSymbol(); ++it) {
|
||||
Symbol *member = *it;
|
||||
if (member->isFriend())
|
||||
continue;
|
||||
else if (! staticLookup && (member->isTypedef() ||
|
||||
member->isEnum() ||
|
||||
member->isClass()))
|
||||
continue;
|
||||
|
||||
addCompletionItem(member);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CppCodeCompletion::completeClass(const QList<Symbol *> &candidates,
|
||||
const DeprecatedLookupContext &context,
|
||||
const DeprecatedLookupContext &deprecatedContext,
|
||||
bool staticLookup)
|
||||
{
|
||||
if (candidates.isEmpty())
|
||||
return;
|
||||
|
||||
Class *klass = candidates.first()->asClass();
|
||||
else if (Symbol *klass = candidates.first()) {
|
||||
LookupContext context(deprecatedContext.expressionDocument(),
|
||||
deprecatedContext.thisDocument(),
|
||||
deprecatedContext.snapshot());
|
||||
|
||||
QList<Scope *> todo;
|
||||
context.expand(klass->members(), context.visibleScopes(), &todo);
|
||||
|
||||
foreach (Scope *scope, todo) {
|
||||
if (! (scope->isClassScope() || scope->isEnumScope()))
|
||||
continue;
|
||||
|
||||
addCompletionItem(scope->owner());
|
||||
|
||||
for (unsigned i = 0; i < scope->symbolCount(); ++i) {
|
||||
Symbol *symbol = scope->symbolAt(i);
|
||||
|
||||
if (symbol->type().isFriend())
|
||||
continue;
|
||||
else if (! staticLookup && (symbol->isTypedef() ||
|
||||
symbol->isEnum() ||
|
||||
symbol->isClass()))
|
||||
continue;
|
||||
|
||||
addCompletionItem(symbol);
|
||||
}
|
||||
if (ClassOrNamespace *binding = context.classOrNamespace(klass))
|
||||
completeClass(binding, context, staticLookup);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1550,8 +1633,8 @@ void CppCodeCompletion::complete(const TextEditor::CompletionItem &item)
|
||||
extraChars += QLatin1Char('<');
|
||||
}
|
||||
} else if (! function->isAmbiguous()) {
|
||||
if (m_spaceAfterFunctionName)
|
||||
extraChars += QLatin1Char(' ');
|
||||
if (m_spaceAfterFunctionName)
|
||||
extraChars += QLatin1Char(' ');
|
||||
extraChars += QLatin1Char('(');
|
||||
|
||||
// If the function doesn't return anything, automatically place the semicolon,
|
||||
|
||||
@@ -50,6 +50,13 @@ class ITextEditor;
|
||||
class BaseTextEditor;
|
||||
}
|
||||
|
||||
namespace CPlusPlus {
|
||||
class LookupItem;
|
||||
class LookupContext;
|
||||
class DeprecatedLookupContext;
|
||||
class ClassOrNamespace;
|
||||
}
|
||||
|
||||
namespace CppTools {
|
||||
namespace Internal {
|
||||
|
||||
@@ -116,9 +123,16 @@ private:
|
||||
bool completeScope(const QList<CPlusPlus::LookupItem> &,
|
||||
const CPlusPlus::DeprecatedLookupContext &context);
|
||||
|
||||
void completeNamespace(CPlusPlus::ClassOrNamespace *binding,
|
||||
const CPlusPlus::LookupContext &context);
|
||||
|
||||
void completeNamespace(const QList<CPlusPlus::Symbol *> &candidates,
|
||||
const CPlusPlus::DeprecatedLookupContext &context);
|
||||
|
||||
void completeClass(CPlusPlus::ClassOrNamespace *b,
|
||||
const CPlusPlus::LookupContext &context,
|
||||
bool staticLookup = true);
|
||||
|
||||
void completeClass(const QList<CPlusPlus::Symbol *> &candidates,
|
||||
const CPlusPlus::DeprecatedLookupContext &context,
|
||||
bool staticLookup = true);
|
||||
|
||||
Reference in New Issue
Block a user