Commit 66a9ef07 authored by Roberto Raggi's avatar Roberto Raggi
Browse files

Ported completeScope(), completeNamespace() and completeClass() to use the new LookupContext.

parent 9eea78d7
......@@ -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,25 +1150,41 @@ 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;
}
if (! classes.isEmpty())
completeClass(classes, context);
} else if (Namespace *nsTy = ty->asNamespaceType()) {
if (ClassOrNamespace *b = context.classOrNamespace(nsTy)) {
completeNamespace(b, context);
break;
}
else if (! namespaces.isEmpty() && m_completions.isEmpty())
completeNamespace(namespaces, context);
}
}
return ! m_completions.isEmpty();
}
......@@ -1295,61 +1312,127 @@ 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::completeClass(const QList<Symbol *> &candidates,
const DeprecatedLookupContext &context,
bool staticLookup)
void CppCodeCompletion::completeNamespace(const QList<Symbol *> &candidates,
const DeprecatedLookupContext &deprecatedContext)
{
if (candidates.isEmpty())
return;
Class *klass = candidates.first()->asClass();
else if (Namespace *ns = candidates.first()->asNamespace()) {
LookupContext context(deprecatedContext.expressionDocument(),
deprecatedContext.thisDocument(),
deprecatedContext.snapshot());
QList<Scope *> todo;
context.expand(klass->members(), context.visibleScopes(), &todo);
if (ClassOrNamespace *binding = context.classOrNamespace(ns))
completeNamespace(binding, context);
}
}
foreach (Scope *scope, todo) {
if (! (scope->isClassScope() || scope->isEnumScope()))
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;
addCompletionItem(scope->owner());
bindingsVisited.insert(binding);
bindingsToVisit += binding->usings();
for (unsigned i = 0; i < scope->symbolCount(); ++i) {
Symbol *symbol = scope->symbolAt(i);
QList<Scope *> scopesToVisit;
QSet<Scope *> scopesVisited;
if (symbol->type().isFriend())
continue;
else if (! staticLookup && (symbol->isTypedef() ||
symbol->isEnum() ||
symbol->isClass()))
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;
addCompletionItem(symbol);
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 &deprecatedContext,
bool staticLookup)
{
if (candidates.isEmpty())
return;
else if (Symbol *klass = candidates.first()) {
LookupContext context(deprecatedContext.expressionDocument(),
deprecatedContext.thisDocument(),
deprecatedContext.snapshot());
if (ClassOrNamespace *binding = context.classOrNamespace(klass))
completeClass(binding, context, staticLookup);
}
}
bool CppCodeCompletion::completeQtMethod(const QList<LookupItem> &results,
const DeprecatedLookupContext &context,
bool wantSignals)
......@@ -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);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment