diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp index 7ce0e42c69df9f16ca6f23b346c78bf98620e9b5..1f4dc9c51af0b2d947e5b3dd8d181f859486c5a7 100644 --- a/src/libs/cplusplus/ResolveExpression.cpp +++ b/src/libs/cplusplus/ResolveExpression.cpp @@ -792,3 +792,69 @@ bool ResolveExpression::visit(PostIncrDecrAST *) { return false; } + +//////////////////////////////////////////////////////////////////////////////// +QList<Symbol *> SymbolsForDotAccess::operator()(NamedType *namedTy, + ResolveExpression::Result p, + const LookupContext &context) +{ + QList<Symbol *> resolvedSymbols; + + if (_blackList.contains(p)) + return resolvedSymbols; + + _blackList.append(p); + + const QList<Symbol *> candidates = + context.resolve(namedTy->name(), context.visibleScopes(p)); + + foreach (Symbol *candidate, candidates) { + if (Class *klass = candidate->asClass()) { + if (resolvedSymbols.contains(klass)) + continue; // we already know about `klass' + resolvedSymbols.append(klass); + } else if (candidate->isTypedef()) { + if (Declaration *decl = candidate->asDeclaration()) { + if (Class *asClass = decl->type()->asClass()) { + // typedef struct { } Point; + // Point pt; + // pt. + resolvedSymbols.append(asClass); + } else { + // typedef Point Boh; + // Boh b; + // b. + const ResolveExpression::Result r(decl->type(), decl); + resolvedSymbols += operator()(r, context); + } + } + } else if (Declaration *decl = candidate->asDeclaration()) { + if (Function *funTy = decl->type()->asFunction()) { + // QString foo("ciao"); + // foo. + if (funTy->scope()->isBlockScope() || funTy->scope()->isNamespaceScope()) { + const ResolveExpression::Result r(funTy->returnType(), decl); + resolvedSymbols += operator()(r, context); + } + } + } + } + + return resolvedSymbols; +} + +QList<Symbol *> SymbolsForDotAccess::operator()(ResolveExpression::Result p, + const LookupContext &context) +{ + FullySpecifiedType ty = p.first; + + if (NamedType *namedTy = ty->asNamedType()) { + return operator()(namedTy, p, context); + } else if (ReferenceType *refTy = ty->asReferenceType()) { + const ResolveExpression::Result e(refTy->elementType(), p.second); + return operator()(e, context); + } + + return QList<Symbol *>(); +} + diff --git a/src/libs/cplusplus/ResolveExpression.h b/src/libs/cplusplus/ResolveExpression.h index ac4a675b459818e493a4b95be0a25be2b8c41a84..35a32c84655e604503d8ba53657353a81fa26e09 100644 --- a/src/libs/cplusplus/ResolveExpression.h +++ b/src/libs/cplusplus/ResolveExpression.h @@ -128,6 +128,20 @@ private: QList<Result> _results; }; +class CPLUSPLUS_EXPORT SymbolsForDotAccess +{ + QList<ResolveExpression::Result> _blackList; + +public: + QList<Symbol *> operator()(NamedType *namedTy, + ResolveExpression::Result p, + const LookupContext &context); + + QList<Symbol *> operator()(ResolveExpression::Result p, + const LookupContext &context); +}; + + } // end of namespace CPlusPlus #endif // CPLUSPLUS_RESOLVEEXPRESSION_H diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp index f8c5fe9b48ad3493c9e9728e79720ac6df5f57f1..075a55b96e96008767490956b909c33345f911f4 100644 --- a/src/plugins/cpptools/cppcodecompletion.cpp +++ b/src/plugins/cpptools/cppcodecompletion.cpp @@ -180,8 +180,6 @@ protected: } // namespace Internal } // namespace CppTools - - using namespace CppTools::Internal; FunctionArgumentWidget::FunctionArgumentWidget(Core::ICore *core) @@ -581,12 +579,12 @@ bool CppCodeCompletion::completeMember(FullySpecifiedType, const QList<TypeOfExpression::Result> &results, const LookupContext &context) { - QTC_ASSERT(!results.isEmpty(), return false); + if (results.isEmpty()) + return false; + const TypeOfExpression::Result p = results.first(); QList<Symbol *> classObjectCandidates; - TypeOfExpression::Result p = results.first(); - if (m_completionOperator == T_ARROW) { FullySpecifiedType ty = p.first; @@ -666,13 +664,13 @@ bool CppCodeCompletion::completeMember(FullySpecifiedType, } if (namedTy) { - const QList<Symbol *> classes = - context.resolveClass(namedTy->name(), - context.visibleScopes(p)); - - foreach (Symbol *c, classes) { - if (! classObjectCandidates.contains(c)) - classObjectCandidates.append(c); + SymbolsForDotAccess symbolsForDotAccess; + const QList<Symbol *> symbols = symbolsForDotAccess(namedTy, p, context); + foreach (Symbol *symbol, symbols) { + if (classObjectCandidates.contains(symbol)) + continue; + if (Class *klass = symbol->asClass()) + classObjectCandidates.append(klass); } } }