summaryrefslogtreecommitdiff
path: root/src/plugins/cpptools
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@nokia.com>2010-05-05 10:59:46 +0200
committerRoberto Raggi <roberto.raggi@nokia.com>2010-05-05 16:36:45 +0200
commit66a9ef072535d33b8876ebc873134fac2d6c7e02 (patch)
treeb40153b5fd1b8466ab7431b938d4ef3020d0587b /src/plugins/cpptools
parent9eea78d7f1df329c25df6fd4cbc113b93d905e36 (diff)
downloadqt-creator-66a9ef072535d33b8876ebc873134fac2d6c7e02.tar.gz
Ported completeScope(), completeNamespace() and completeClass() to use the new LookupContext.
Diffstat (limited to 'src/plugins/cpptools')
-rw-r--r--src/plugins/cpptools/cppcodecompletion.cpp169
-rw-r--r--src/plugins/cpptools/cppcodecompletion.h14
2 files changed, 140 insertions, 43 deletions
diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp
index 519dd69ed5..a5f583254c 100644
--- a/src/plugins/cpptools/cppcodecompletion.cpp
+++ b/src/plugins/cpptools/cppcodecompletion.cpp
@@ -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,
diff --git a/src/plugins/cpptools/cppcodecompletion.h b/src/plugins/cpptools/cppcodecompletion.h
index e7d171f6dc..76090459c5 100644
--- a/src/plugins/cpptools/cppcodecompletion.h
+++ b/src/plugins/cpptools/cppcodecompletion.h
@@ -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);