diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp index ca7d379f5721fa3067f3e878571b4bc0882daa91..9c367d1ab7c26fec021ca52c7e31502e6cc651b5 100644 --- a/src/libs/cplusplus/FindUsages.cpp +++ b/src/libs/cplusplus/FindUsages.cpp @@ -282,14 +282,14 @@ void FindUsages::checkExpression(unsigned startToken, unsigned endToken) // qDebug() << "*** check expression:" << expression; TypeOfExpression typeofExpression; - typeofExpression.setSnapshot(_snapshot); + typeofExpression.init(_doc, _snapshot); unsigned line, column; getTokenStartPosition(startToken, &line, &column); Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column); - const QList<LookupItem> results = typeofExpression(expression, _doc, lastVisibleSymbol, - TypeOfExpression::Preprocess); + const QList<LookupItem> results = typeofExpression(expression, lastVisibleSymbol, + TypeOfExpression::Preprocess); QList<Symbol *> candidates; diff --git a/src/libs/cplusplus/GenTemplateInstance.cpp b/src/libs/cplusplus/GenTemplateInstance.cpp index b430e458f6b5c634b188534a8e4244eafd3e7d72..bb6afc6655e42621223e28f7e1c8c11146e65a8d 100644 --- a/src/libs/cplusplus/GenTemplateInstance.cpp +++ b/src/libs/cplusplus/GenTemplateInstance.cpp @@ -47,10 +47,10 @@ namespace { class ApplySubstitution { public: - ApplySubstitution(const DeprecatedLookupContext &context, Symbol *symbol, const GenTemplateInstance::Substitution &substitution); + ApplySubstitution(Control *control, Symbol *symbol, const GenTemplateInstance::Substitution &substitution); ~ApplySubstitution(); - Control *control() const { return context.control(); } + inline Control *control() const { return _control; } FullySpecifiedType apply(const Name *name); FullySpecifiedType apply(const FullySpecifiedType &type); @@ -309,16 +309,16 @@ private: }; public: // attributes - DeprecatedLookupContext context; + Control *_control; Symbol *symbol; GenTemplateInstance::Substitution substitution; ApplyToType applyToType; ApplyToName applyToName; }; -ApplySubstitution::ApplySubstitution(const DeprecatedLookupContext &context, Symbol *symbol, +ApplySubstitution::ApplySubstitution(Control *control, Symbol *symbol, const GenTemplateInstance::Substitution &substitution) - : context(context), symbol(symbol), + : _control(control), symbol(symbol), substitution(substitution), applyToType(this), applyToName(this) { } @@ -363,17 +363,17 @@ FullySpecifiedType ApplySubstitution::applySubstitution(int index) const } // end of anonymous namespace -GenTemplateInstance::GenTemplateInstance(const DeprecatedLookupContext &context, const Substitution &substitution) +GenTemplateInstance::GenTemplateInstance(Control *control, const Substitution &substitution) : _symbol(0), - _context(context), + _control(control), _substitution(substitution) { } FullySpecifiedType GenTemplateInstance::operator()(Symbol *symbol) { - ApplySubstitution o(_context, symbol, _substitution); + ApplySubstitution o(_control, symbol, _substitution); return o.apply(symbol->type()); } Control *GenTemplateInstance::control() const -{ return _context.control(); } +{ return _control; } diff --git a/src/libs/cplusplus/GenTemplateInstance.h b/src/libs/cplusplus/GenTemplateInstance.h index 6225c0bfb5240ad49eb1b2434a93de2af1a8b12c..b667cc2ab412e2e02a5e435a3a5076d6beafd73d 100644 --- a/src/libs/cplusplus/GenTemplateInstance.h +++ b/src/libs/cplusplus/GenTemplateInstance.h @@ -47,7 +47,7 @@ public: typedef QList< QPair<const Identifier *, FullySpecifiedType> > Substitution; public: - GenTemplateInstance(const DeprecatedLookupContext &context, const Substitution &substitution); + GenTemplateInstance(Control *control, const Substitution &substitution); FullySpecifiedType operator()(Symbol *symbol); @@ -55,7 +55,7 @@ public: private: Symbol *_symbol; - DeprecatedLookupContext _context; + Control *_control; const Substitution _substitution; }; diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 36fd3de8df6021209783a7c2e2737f5f641cd58f..27fdbb30f83dfd063de18df217e9f776996bcc30 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -148,6 +148,16 @@ ClassOrNamespace *LookupContext::classOrNamespace(const Name *name, Symbol *last return classOrNamespace(name, lastVisibleSymbol); } +QList<Symbol *> LookupContext::lookup(const Name *name, Symbol *lastVisibleSymbol) const +{ + Scope *scope = _thisDocument->globalSymbols(); + + if (lastVisibleSymbol && lastVisibleSymbol->scope()) + scope = lastVisibleSymbol->scope(); + + return lookup(name, scope); +} + QList<Symbol *> LookupContext::lookup(const Name *name, Scope *scope) const { QList<Symbol *> candidates; @@ -168,19 +178,15 @@ QList<Symbol *> LookupContext::lookup(const Name *name, Scope *scope) const Symbol *member = scope->symbolAt(index); if (UsingNamespaceDirective *u = member->asUsingNamespaceDirective()) { - Namespace *enclosingNamespace = u->enclosingNamespaceScope()->owner()->asNamespace(); - //qDebug() << "*** enclosing namespace:" << enclosingNamespace; - Q_ASSERT(enclosingNamespace != 0); - - ClassOrNamespace *b = bindings()->findClassOrNamespace(enclosingNamespace); - //qDebug() << "**** binding:" << b; - Q_ASSERT(b != 0); - - if (ClassOrNamespace *uu = b->lookupClassOrNamespace(u->name())) { - candidates = uu->lookup(name); - - if (! candidates.isEmpty()) - return candidates; + if (Namespace *enclosingNamespace = u->enclosingNamespaceScope()->owner()->asNamespace()) { + if (ClassOrNamespace *b = bindings()->findClassOrNamespace(enclosingNamespace)) { + if (ClassOrNamespace *uu = b->lookupClassOrNamespace(u->name())) { + candidates = uu->lookup(name); + + if (! candidates.isEmpty()) + return candidates; + } + } } } } diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h index ad8f43f268266c386d1ce28c5bf427e9ffb8a596..0937e86a0b7232041aa01bd83b68e2228edd9aa4 100644 --- a/src/libs/cplusplus/LookupContext.h +++ b/src/libs/cplusplus/LookupContext.h @@ -174,6 +174,7 @@ public: Document::Ptr document(const QString &fileName) const; Snapshot snapshot() const; + QList<Symbol *> lookup(const Name *name, Symbol *lastVisibleSymbol) const; QList<Symbol *> lookup(const Name *name, Scope *scope) const; ClassOrNamespace *globalNamespace() const; @@ -188,7 +189,7 @@ public: /// \internal void setBindings(QSharedPointer<CreateBindings> bindings); - Q_DECL_DEPRECATED Control *control() const; + Control *control() const; // ### deprecate private: Control *_control; diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp index 9fc10b6d16e2a022ec3777b3deabc48bb40ca802..1825de4381116093faf2fae30dae4d50c2d4a219 100644 --- a/src/libs/cplusplus/ResolveExpression.cpp +++ b/src/libs/cplusplus/ResolveExpression.cpp @@ -28,7 +28,7 @@ **************************************************************************/ #include "ResolveExpression.h" -#include "DeprecatedLookupContext.h" +#include "LookupContext.h" #include "Overview.h" #include "GenTemplateInstance.h" @@ -43,7 +43,6 @@ #include <NameVisitor.h> #include <QtCore/QList> -#include <QtCore/QVarLengthArray> #include <QtCore/QtDebug> using namespace CPlusPlus; @@ -71,8 +70,21 @@ static QList<_Tp> removeDuplicates(const QList<_Tp> &results) ///////////////////////////////////////////////////////////////////// // ResolveExpression ///////////////////////////////////////////////////////////////////// -ResolveExpression::ResolveExpression(const DeprecatedLookupContext &context) +ResolveExpression::ResolveExpression(Symbol *lastVisibleSymbol, const LookupContext &context) : ASTVisitor(context.expressionDocument()->translationUnit()), + _lastVisibleSymbol(lastVisibleSymbol), + _context(context), + sem(context.expressionDocument()->translationUnit()) +{ + if (! lastVisibleSymbol) + lastVisibleSymbol = context.thisDocument()->globalNamespace(); + _scope = lastVisibleSymbol->scope(); +} + +ResolveExpression::ResolveExpression(Scope *scope, const LookupContext &context) + : ASTVisitor(context.expressionDocument()->translationUnit()), + _lastVisibleSymbol(0), + _scope(scope), _context(context), sem(context.expressionDocument()->translationUnit()) { } @@ -102,21 +114,25 @@ void ResolveExpression::addResults(const QList<LookupItem> &results) } void ResolveExpression::addResult(const FullySpecifiedType &ty, Symbol *symbol) -{ return addResult(LookupItem(ty, symbol)); } - -void ResolveExpression::addResult(const LookupItem &r) { - LookupItem p = r; + if (! symbol) { + if (_scope) + symbol = _scope->owner(); - if (! p.lastVisibleSymbol()) - p.setLastVisibleSymbol(_context.symbol()); + else + symbol = _context.thisDocument()->globalNamespace(); + } - if (! _results.contains(p)) - _results.append(p); + return addResult(LookupItem(ty, symbol)); } -QList<Scope *> ResolveExpression::visibleScopes(const LookupItem &result) const -{ return _context.visibleScopes(result); } +void ResolveExpression::addResult(const LookupItem &r) +{ + Q_ASSERT(r.lastVisibleSymbol() != 0); + + if (! _results.contains(r)) + _results.append(r); +} bool ResolveExpression::visit(BinaryExpressionAST *ast) { @@ -289,10 +305,7 @@ bool ResolveExpression::visit(ThisExpressionAST *) void ResolveExpression::thisObject() { - if (! _context.symbol()) - return; - - Scope *scope = _context.symbol()->scope(); + Scope *scope = _scope; for (; scope; scope = scope->enclosingScope()) { if (scope->isFunctionScope()) { Function *fun = scope->owner()->asFunction(); @@ -387,42 +400,28 @@ bool ResolveExpression::visit(CompoundLiteralAST *ast) bool ResolveExpression::visit(QualifiedNameAST *ast) { - ResolveClass resolveClass; - const Name *name = ast->name; - - QList<Symbol *> symbols = _context.resolve(name); - foreach (Symbol *symbol, symbols) { - if (symbol->isTypedef()) { - if (NamedType *namedTy = symbol->type()->asNamedType()) { - const LookupItem r(namedTy, symbol); - const QList<Symbol *> resolvedClasses = - resolveClass(namedTy->name(), r, _context); - if (resolvedClasses.count()) { - foreach (Symbol *s, resolvedClasses) { - addResult(s->type(), s); - } - continue; - } - } - } - addResult(symbol->type(), symbol); + if (const Name *name = ast->name) { + const QList<Symbol *> candidates = _context.lookup(name, _scope); + + foreach (Symbol *candidate, candidates) + addResult(candidate->type(), candidate); } - return false; -} -bool ResolveExpression::visit(OperatorFunctionIdAST *) -{ return false; } -bool ResolveExpression::visit(ConversionFunctionIdAST *) +bool ResolveExpression::visit(SimpleNameAST *ast) { + QList<Symbol *> symbols = _context.lookup(ast->name, _scope); + foreach (Symbol *symbol, symbols) + addResult(symbol->type(), symbol); + return false; } -bool ResolveExpression::visit(SimpleNameAST *ast) +bool ResolveExpression::visit(TemplateIdAST *ast) { - QList<Symbol *> symbols = _context.resolve(ast->name); + const QList<Symbol *> symbols = _context.lookup(ast->name, _scope); foreach (Symbol *symbol, symbols) addResult(symbol->type(), symbol); @@ -436,12 +435,13 @@ bool ResolveExpression::visit(DestructorNameAST *) return false; } -bool ResolveExpression::visit(TemplateIdAST *ast) +bool ResolveExpression::visit(OperatorFunctionIdAST *) { - QList<Symbol *> symbols = _context.resolve(ast->name); - foreach (Symbol *symbol, symbols) - addResult(symbol->type(), symbol); + return false; +} +bool ResolveExpression::visit(ConversionFunctionIdAST *) +{ return false; } @@ -470,8 +470,6 @@ bool ResolveExpression::maybeValidPrototype(Function *funTy, unsigned actualArgu bool ResolveExpression::visit(CallAST *ast) { - ResolveClass resolveClass; - const QList<LookupItem> baseResults = _results; _results.clear(); @@ -491,17 +489,13 @@ bool ResolveExpression::visit(CallAST *ast) Symbol *lastVisibleSymbol = result.lastVisibleSymbol(); if (NamedType *namedTy = ty->asNamedType()) { - const QList<Symbol *> classObjectCandidates = resolveClass(namedTy->name(), result, _context); - - foreach (Symbol *classObject, classObjectCandidates) { - const QList<LookupItem> overloads = resolveMember(functionCallOp, classObject->asClass(), namedTy->name()); - - foreach (const LookupItem &o, overloads) { - FullySpecifiedType overloadTy = o.type().simplified(); - - if (Function *funTy = overloadTy->asFunctionType()) { - if (maybeValidPrototype(funTy, actualArgumentCount)) - addResult(funTy->returnType().simplified(), lastVisibleSymbol); + if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), lastVisibleSymbol->scope())) { + foreach (Symbol *overload, b->lookup(functionCallOp)) { + if (Function *funTy = overload->type()->asFunctionType()) { + if (maybeValidPrototype(funTy, actualArgumentCount)) { + Function *proto = instantiate(namedTy->name(), funTy)->asFunctionType(); + addResult(proto->returnType().simplified(), lastVisibleSymbol); + } } } } @@ -526,37 +520,29 @@ bool ResolveExpression::visit(ArrayAccessAST *ast) _results.clear(); const QList<LookupItem> indexResults = operator()(ast->expression); - ResolveClass resolveClass; const Name *arrayAccessOp = control()->operatorNameId(OperatorNameId::ArrayAccessOp); foreach (const LookupItem &result, baseResults) { FullySpecifiedType ty = result.type().simplified(); - Symbol *contextSymbol = result.lastVisibleSymbol(); + Symbol *lastVisibleSymbol = result.lastVisibleSymbol(); if (PointerType *ptrTy = ty->asPointerType()) { - addResult(ptrTy->elementType().simplified(), contextSymbol); + addResult(ptrTy->elementType().simplified(), lastVisibleSymbol); } else if (ArrayType *arrTy = ty->asArrayType()) { - addResult(arrTy->elementType().simplified(), contextSymbol); + addResult(arrTy->elementType().simplified(), lastVisibleSymbol); } else if (NamedType *namedTy = ty->asNamedType()) { - const QList<Symbol *> classObjectCandidates = - resolveClass(namedTy->name(), result, _context); - - foreach (Symbol *classObject, classObjectCandidates) { - Q_ASSERT(classObject->isClass()); - - const QList<LookupItem> overloads = - resolveMember(arrayAccessOp, classObject->asClass(), namedTy->name()); - - foreach (LookupItem r, overloads) { - FullySpecifiedType ty = r.type().simplified(); - if (Function *funTy = ty->asFunctionType()) { - ty = funTy->returnType().simplified(); - addResult(ty, funTy); + if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), lastVisibleSymbol->scope())) { + foreach (Symbol *overload, b->lookup(arrayAccessOp)) { + if (Function *funTy = overload->type()->asFunctionType()) { + Function *proto = instantiate(namedTy->name(), funTy)->asFunctionType(); + // ### TODO: check the actual arguments + addResult(proto->returnType().simplified(), lastVisibleSymbol); } } + } } } @@ -567,7 +553,7 @@ bool ResolveExpression::visit(MemberAccessAST *ast) { // The candidate types for the base expression are stored in // _results. - QList<LookupItem> baseResults = _results; + const QList<LookupItem> baseResults = _results; // Evaluate the expression-id that follows the access operator. const Name *memberName = 0; @@ -601,56 +587,23 @@ ResolveExpression::resolveBaseExpression(const QList<LookupItem> &baseResults, i } if (accessOp == T_ARROW) { - if (lastVisibleSymbol && ty->isClassType() && ! lastVisibleSymbol->isClass()) { - // ### remove ! lastVisibleSymbol->isClass() from the condition. - results.append(LookupItem(ty, lastVisibleSymbol)); - - } else if (NamedType *namedTy = ty->asNamedType()) { - // ### This code is pretty slow. - const QList<Symbol *> candidates = _context.resolve(namedTy->name()); - - foreach (Symbol *candidate, candidates) { - if (candidate->isTypedef()) { - FullySpecifiedType declTy = candidate->type().simplified(); - const LookupItem r(declTy, candidate); - - // update the result - result = r; - - // refresh the cached ty and lastVisibileSymbol. - ty = result.type().simplified(); - lastVisibleSymbol = result.lastVisibleSymbol(); - break; - } - } - } - if (NamedType *namedTy = ty->asNamedType()) { - ResolveClass resolveClass; const Name *arrowAccessOp = control()->operatorNameId(OperatorNameId::ArrowOp); - const QList<Symbol *> candidates = resolveClass(namedTy->name(), result, _context); - - foreach (Symbol *classObject, candidates) { - const QList<LookupItem> overloads = resolveMember(arrowAccessOp, classObject->asClass(), - namedTy->name()); - - foreach (const LookupItem &r, overloads) { - FullySpecifiedType typeOfOverloadFunction = r.type().simplified(); - Symbol *lastVisibleSymbol = r.lastVisibleSymbol(); - Function *funTy = typeOfOverloadFunction->asFunctionType(); - if (! funTy) - continue; - typeOfOverloadFunction = funTy->returnType().simplified(); + if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), result.lastVisibleSymbol()->scope())) { + foreach (Symbol *overload, b->lookup(arrowAccessOp)) { + if (Function *funTy = overload->type()->asFunctionType()) { + FullySpecifiedType f = instantiate(namedTy->name(), funTy); + FullySpecifiedType retTy = f->asFunctionType()->returnType().simplified(); - if (PointerType *ptrTy = typeOfOverloadFunction->asPointerType()) { - FullySpecifiedType elementTy = ptrTy->elementType().simplified(); - - if (elementTy->isNamedType()) - results.append(LookupItem(elementTy, lastVisibleSymbol)); + if (PointerType *ptrTy = retTy->asPointerType()) { + FullySpecifiedType elementTy = ptrTy->elementType().simplified(); + results.append(LookupItem(elementTy, overload)); + } } } } + } else if (PointerType *ptrTy = ty->asPointerType()) { FullySpecifiedType elementTy = ptrTy->elementType().simplified(); @@ -669,8 +622,7 @@ ResolveExpression::resolveBaseExpression(const QList<LookupItem> &baseResults, i } if (NamedType *namedTy = ty->asNamedType()) { - const QList<Scope *> visibleScopes = _context.visibleScopes(result); - const QList<Symbol *> candidates = _context.resolve(namedTy->name(), visibleScopes); + const QList<Symbol *> candidates = _context.lookup(namedTy->name(), result.lastVisibleSymbol()); foreach (Symbol *candidate, candidates) { if (candidate->isTypedef() && candidate->type()->isNamedType()) { ty = candidate->type(); @@ -704,10 +656,10 @@ ResolveExpression::resolveMemberExpression(const QList<LookupItem> &baseResults, const Name *memberName, bool *replacedDotOperator) const { - ResolveClass resolveClass; QList<LookupItem> results; const QList<LookupItem> classObjectResults = resolveBaseExpression(baseResults, accessOp, replacedDotOperator); + foreach (const LookupItem &r, classObjectResults) { FullySpecifiedType ty = r.type(); @@ -715,12 +667,9 @@ ResolveExpression::resolveMemberExpression(const QList<LookupItem> &baseResults, results += resolveMember(memberName, klass); else if (NamedType *namedTy = ty->asNamedType()) { - const Name *className = namedTy->name(); - const QList<Symbol *> classes = resolveClass(className, r, _context); - - foreach (Symbol *c, classes) { - if (Class *klass = c->asClass()) - results += resolveMember(memberName, klass, className); + if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), r.lastVisibleSymbol()->scope())) { + foreach (Symbol *c, b->lookup(memberName)) + results.append(LookupItem(instantiate(namedTy->name(), c), c)); } } } @@ -728,22 +677,49 @@ ResolveExpression::resolveMemberExpression(const QList<LookupItem> &baseResults, return removeDuplicates(results); } +FullySpecifiedType ResolveExpression::instantiate(const Name *className, Symbol *candidate) const +{ + if (const TemplateNameId *templId = className->asTemplateNameId()) { + if (Class *klass = candidate->enclosingSymbol()->asClass()) { + GenTemplateInstance::Substitution subst; + + for (unsigned i = 0; i < templId->templateArgumentCount(); ++i) { + FullySpecifiedType templArgTy = templId->templateArgumentAt(i); + + if (i < klass->templateParameterCount()) { + const Name *templArgName = klass->templateParameterAt(i)->name(); + + if (templArgName && templArgName->identifier()) { + const Identifier *templArgId = templArgName->identifier(); + subst.append(qMakePair(templArgId, templArgTy)); + } + } + } + + GenTemplateInstance inst(_context.control(), subst); + return inst(candidate); + } + } + + return candidate->type(); +} + QList<LookupItem> ResolveExpression::resolveMember(const Name *memberName, Class *klass, const Name *className) const { QList<LookupItem> results; + if (! klass) + return results; + if (! className) className = klass->name(); if (! className) return results; - QList<Scope *> scopes; - _context.expand(klass->members(), _context.visibleScopes(), &scopes); - - const QList<Symbol *> candidates = _context.resolve(memberName, scopes); + const QList<Symbol *> candidates = _context.lookup(memberName, klass->members()); foreach (Symbol *candidate, candidates) { FullySpecifiedType ty = candidate->type(); @@ -767,7 +743,7 @@ ResolveExpression::resolveMember(const Name *memberName, Class *klass, } } - GenTemplateInstance inst(_context, subst); + GenTemplateInstance inst(_context.control(), subst); ty = inst(candidate); } @@ -782,14 +758,10 @@ QList<LookupItem> ResolveExpression::resolveMember(const Name *memberName, ObjCClass *klass) const { QList<LookupItem> results; - if (!memberName || !klass) return results; - QList<Scope *> scopes; - _context.expand(klass->members(), _context.visibleScopes(), &scopes); - - QList<Symbol *> candidates = _context.resolve(memberName, scopes); + const QList<Symbol *> candidates = _context.lookup(memberName, klass->members()); foreach (Symbol *candidate, candidates) { FullySpecifiedType ty = candidate->type(); @@ -828,8 +800,7 @@ bool ResolveExpression::visit(ObjCMessageExpressionAST *ast) } if (klassName&&ast->selector && ast->selector->name) { - ResolveObjCClass resolveObjCClass; - QList<Symbol *> resolvedSymbols = resolveObjCClass(klassName, result, _context); + const QList<Symbol *> resolvedSymbols = _context.lookup(klassName, result.lastVisibleSymbol()); foreach (Symbol *resolvedSymbol, resolvedSymbols) if (ObjCClass *klass = resolvedSymbol->asObjCClass()) _results.append(resolveMember(ast->selector->name, klass)); @@ -839,103 +810,3 @@ bool ResolveExpression::visit(ObjCMessageExpressionAST *ast) return false; } -//////////////////////////////////////////////////////////////////////////////// -ResolveClass::ResolveClass() -{ } - -QList<Symbol *> ResolveClass::operator()(const Name *name, - const LookupItem &p, - const DeprecatedLookupContext &context) -{ - const QList<LookupItem> previousBlackList = _blackList; - const QList<Symbol *> symbols = resolveClass(name, p, context); - _blackList = previousBlackList; - return symbols; -} - -QList<Symbol *> ResolveClass::resolveClass(const Name *name, - const LookupItem &p, - const DeprecatedLookupContext &context) -{ - QList<Symbol *> resolvedSymbols; - - if (_blackList.contains(p)) - return resolvedSymbols; - - _blackList.append(p); - - const QList<Symbol *> candidates = - context.resolve(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()->asClassType()) { - // typedef struct { } Point; - // Point pt; - // pt. - resolvedSymbols.append(asClass); - } else { - // typedef Point Boh; - // Boh b; - // b. - FullySpecifiedType declType = decl->type().simplified(); - if (NamedType *namedTy = declType->asNamedType()) { - const LookupItem r(declType, decl); - resolvedSymbols += resolveClass(namedTy->name(), r, context); - } - } - } - } else if (Declaration *decl = candidate->asDeclaration()) { - if (Function *funTy = decl->type()->asFunctionType()) { - // QString foo("ciao"); - // foo. - if (funTy->scope() && (funTy->scope()->isBlockScope() || funTy->scope()->isNamespaceScope())) { - FullySpecifiedType retTy = funTy->returnType().simplified(); - if (NamedType *namedTy = retTy->asNamedType()) { - const LookupItem r(retTy, decl); - resolvedSymbols += resolveClass(namedTy->name(), r, context); - } - } - } - } - } - - return resolvedSymbols; -} - -ResolveObjCClass::ResolveObjCClass() -{} - -QList<Symbol *> ResolveObjCClass::operator ()(const Name *name, - const LookupItem &p, - const DeprecatedLookupContext &context) -{ - QList<Symbol *> resolvedSymbols; - - const QList<Symbol *> candidates = - context.resolve(name, context.visibleScopes(p)); - - foreach (Symbol *candidate, candidates) { - if (ObjCClass *klass = candidate->asObjCClass()) { - if (resolvedSymbols.contains(klass)) - continue; // we already know about `klass' - resolvedSymbols.append(klass); - } else if (candidate->isTypedef()) { - if (Declaration *decl = candidate->asDeclaration()) { - if (decl->type()->isObjCClassType()) { - ObjCClass *klass = decl->type()->asObjCClassType(); - if (resolvedSymbols.contains(klass)) - continue; - resolvedSymbols.append(klass); - } - } - } - } - - return resolvedSymbols; -} diff --git a/src/libs/cplusplus/ResolveExpression.h b/src/libs/cplusplus/ResolveExpression.h index 8f7e6fb85af01f1daf985a3de97ceed226884b55..d1fbc84e2fddf3d4e55518f01f14f9d541162edf 100644 --- a/src/libs/cplusplus/ResolveExpression.h +++ b/src/libs/cplusplus/ResolveExpression.h @@ -30,7 +30,7 @@ #ifndef CPLUSPLUS_RESOLVEEXPRESSION_H #define CPLUSPLUS_RESOLVEEXPRESSION_H -#include "DeprecatedLookupContext.h" +#include "LookupContext.h" #include <ASTVisitor.h> #include <Semantic.h> @@ -41,27 +41,30 @@ namespace CPlusPlus { class CPLUSPLUS_EXPORT ResolveExpression: protected ASTVisitor { public: - ResolveExpression(const DeprecatedLookupContext &context); + ResolveExpression(Symbol *lastVisibleSymbol, const LookupContext &context); + ResolveExpression(Scope *scope, const LookupContext &context); + virtual ~ResolveExpression(); QList<LookupItem> operator()(ExpressionAST *ast); QList<LookupItem> resolveMemberExpression(const QList<LookupItem> &baseResults, - unsigned accessOp, - const Name *memberName, - bool *replacedDotOperator = 0) const; + unsigned accessOp, + const Name *memberName, + bool *replacedDotOperator = 0) const; QList<LookupItem> resolveBaseExpression(const QList<LookupItem> &baseResults, - int accessOp, - bool *replacedDotOperator = 0) const; + int accessOp, + bool *replacedDotOperator = 0) const; - QList<LookupItem> resolveMember(const Name *memberName, Class *klass, - const Name *className = 0) const; + Q_DECL_DEPRECATED QList<LookupItem> resolveMember(const Name *memberName, Class *klass, + const Name *className = 0) const; - QList<LookupItem> resolveMember(const Name *memberName, ObjCClass *klass) const; + Q_DECL_DEPRECATED QList<LookupItem> resolveMember(const Name *memberName, ObjCClass *klass) const; protected: QList<LookupItem> switchResults(const QList<LookupItem> &symbols); + FullySpecifiedType instantiate(const Name *className, Symbol *candidate) const; void thisObject(); void addResult(const FullySpecifiedType &ty, Symbol *symbol = 0); @@ -113,44 +116,15 @@ protected: // Objective-C expressions virtual bool visit(ObjCMessageExpressionAST *ast); - QList<Scope *> visibleScopes(const LookupItem &result) const; - private: - DeprecatedLookupContext _context; + Symbol *_lastVisibleSymbol; + Scope *_scope; + LookupContext _context; Semantic sem; QList<LookupItem> _results; Symbol *_declSymbol; }; -class CPLUSPLUS_EXPORT ResolveClass -{ -public: - ResolveClass(); - - QList<Symbol *> operator()(const Name *name, - const LookupItem &p, - const DeprecatedLookupContext &context); - -private: - QList<Symbol *> resolveClass(const Name *name, - const LookupItem &p, - const DeprecatedLookupContext &context); - -private: - QList<LookupItem> _blackList; -}; - -class CPLUSPLUS_EXPORT ResolveObjCClass -{ -public: - ResolveObjCClass(); - - QList<Symbol *> operator()(const Name *name, - const LookupItem &p, - const DeprecatedLookupContext &context); -}; - - } // end of namespace CPlusPlus #endif // CPLUSPLUS_RESOLVEEXPRESSION_H diff --git a/src/libs/cplusplus/TypeOfExpression.cpp b/src/libs/cplusplus/TypeOfExpression.cpp index cfad0b737d855e2be48954cf5fdf82f5e675b82e..cfe8ac74e990067e4ea3a93ac641884f6a52e185 100644 --- a/src/libs/cplusplus/TypeOfExpression.cpp +++ b/src/libs/cplusplus/TypeOfExpression.cpp @@ -29,7 +29,7 @@ #include "TypeOfExpression.h" #include <TranslationUnit.h> -#include "DeprecatedLookupContext.h" +#include "LookupContext.h" #include "ResolveExpression.h" #include "pp.h" @@ -39,44 +39,59 @@ using namespace CPlusPlus; TypeOfExpression::TypeOfExpression(): - m_ast(0) + m_ast(0), + m_lastVisibleSymbol(0) { } -Snapshot TypeOfExpression::snapshot() const +void TypeOfExpression::reset() { - return m_snapshot; + m_thisDocument.clear(); + m_snapshot = Snapshot(); + m_ast = 0; + m_lastVisibleSymbol = 0; + m_lookupContext = LookupContext(); + m_bindings.clear(); + m_environment.clear(); } -void TypeOfExpression::setSnapshot(const Snapshot &documents) +void TypeOfExpression::init(Document::Ptr thisDocument, const Snapshot &snapshot, + QSharedPointer<CreateBindings> bindings) { - m_snapshot = documents; - m_lookupContext = DeprecatedLookupContext(); + m_thisDocument = thisDocument; + m_snapshot = snapshot; + m_ast = 0; + m_lastVisibleSymbol = 0; + m_lookupContext = LookupContext(); + m_bindings = bindings; + m_environment.clear(); } QList<LookupItem> TypeOfExpression::operator()(const QString &expression, - Document::Ptr document, - Symbol *lastVisibleSymbol, - PreprocessMode mode) + Symbol *lastVisibleSymbol, + PreprocessMode mode) { QString code = expression; + if (mode == Preprocess) - code = preprocessedExpression(expression, m_snapshot, document); + code = preprocessedExpression(expression); + Document::Ptr expressionDoc = documentForExpression(code); expressionDoc->check(); m_ast = extractExpressionAST(expressionDoc); - m_lookupContext = DeprecatedLookupContext(lastVisibleSymbol, expressionDoc, - document, m_snapshot); + m_lastVisibleSymbol = lastVisibleSymbol; + + m_lookupContext = LookupContext(expressionDoc, m_thisDocument, m_snapshot); + m_lookupContext.setBindings(m_bindings); - ResolveExpression resolveExpression(m_lookupContext); + ResolveExpression resolveExpression(lastVisibleSymbol, m_lookupContext); return resolveExpression(m_ast); } -QString TypeOfExpression::preprocess(const QString &expression, - Document::Ptr document) const +QString TypeOfExpression::preprocess(const QString &expression) const { - return preprocessedExpression(expression, m_snapshot, document); + return preprocessedExpression(expression); } ExpressionAST *TypeOfExpression::ast() const @@ -84,7 +99,12 @@ ExpressionAST *TypeOfExpression::ast() const return m_ast; } -const DeprecatedLookupContext &TypeOfExpression::lookupContext() const +Symbol *TypeOfExpression::lastVisibleSymbol() const +{ + return m_lastVisibleSymbol; +} + +const LookupContext &TypeOfExpression::lookupContext() const { return m_lookupContext; } @@ -112,37 +132,35 @@ Document::Ptr TypeOfExpression::documentForExpression(const QString &expression) return doc; } -void TypeOfExpression::processEnvironment(Snapshot documents, - Document::Ptr doc, Environment *env, +void TypeOfExpression::processEnvironment(Document::Ptr doc, Environment *env, QSet<QString> *processed) const { - if (! doc) - return; - if (processed->contains(doc->fileName())) - return; - processed->insert(doc->fileName()); - foreach (const Document::Include &incl, doc->includes()) { - processEnvironment(documents, - documents.document(incl.fileName()), - env, processed); + if (doc && ! processed->contains(doc->fileName())) { + processed->insert(doc->fileName()); + + foreach (const Document::Include &incl, doc->includes()) + processEnvironment(m_snapshot.document(incl.fileName()), env, processed); + + foreach (const Macro ¯o, doc->definedMacros()) + env->bind(macro); } - foreach (const Macro ¯o, doc->definedMacros()) - env->bind(macro); } -QString TypeOfExpression::preprocessedExpression(const QString &expression, - Snapshot documents, - Document::Ptr thisDocument) const +QString TypeOfExpression::preprocessedExpression(const QString &expression) const { if (expression.trimmed().isEmpty()) return expression; - Environment env; - QSet<QString> processed; - processEnvironment(documents, thisDocument, - &env, &processed); + if (! m_environment) { + Environment *env = new Environment(); // ### cache the environment. + + QSet<QString> processed; + processEnvironment(m_thisDocument, env, &processed); + m_environment = QSharedPointer<Environment>(env); + } + const QByteArray code = expression.toUtf8(); - Preprocessor preproc(0, &env); + Preprocessor preproc(0, m_environment.data()); const QByteArray preprocessedCode = preproc("<expression>", code); return QString::fromUtf8(preprocessedCode.constData(), preprocessedCode.size()); } diff --git a/src/libs/cplusplus/TypeOfExpression.h b/src/libs/cplusplus/TypeOfExpression.h index 245911588723d1fb21d95bcc847ecd72f89b423a..b2c181a419bcf3f8006e05b8c8138c9f60c3b88e 100644 --- a/src/libs/cplusplus/TypeOfExpression.h +++ b/src/libs/cplusplus/TypeOfExpression.h @@ -30,7 +30,8 @@ #define CPLUSPLUS_TYPEOFEXPRESSION_H #include "CppDocument.h" -#include "DeprecatedLookupContext.h" +#include "LookupContext.h" +#include "PreprocessorEnvironment.h" #include <ASTfwd.h> #include <QtCore/QMap> @@ -44,11 +45,11 @@ class Macro; class CPLUSPLUS_EXPORT TypeOfExpression { + Q_DISABLE_COPY(TypeOfExpression) + public: TypeOfExpression(); - Snapshot snapshot() const; - /** * Sets the documents used to evaluate expressions. Should be set before * calling this functor. @@ -56,7 +57,10 @@ public: * Also clears the lookup context, so can be used to make sure references * to the documents previously used are removed. */ - void setSnapshot(const Snapshot &documents); + void init(Document::Ptr thisDocument, const Snapshot &snapshot, + QSharedPointer<CreateBindings> bindings = QSharedPointer<CreateBindings>()); + + void reset(); enum PreprocessMode { NoPreprocess, @@ -72,14 +76,13 @@ public: * has been made! * * @param expression The expression to evaluate. - * @param document The document the expression is part of. * @param lastVisibleSymbol The last visible symbol in the document. */ - QList<LookupItem> operator()(const QString &expression, Document::Ptr document, - Symbol *lastVisibleSymbol, - PreprocessMode mode = NoPreprocess); + QList<LookupItem> operator()(const QString &expression, + Symbol *lastVisibleSymbol, + PreprocessMode mode = NoPreprocess); - QString preprocess(const QString &expression, Document::Ptr document) const; + QString preprocess(const QString &expression) const; /** * Returns the AST of the last evaluated expression. @@ -89,7 +92,8 @@ public: /** * Returns the lookup context of the last evaluated expression. */ - const DeprecatedLookupContext &lookupContext() const; + const LookupContext &lookupContext() const; + Symbol *lastVisibleSymbol() const; ExpressionAST *expressionAST() const; @@ -97,17 +101,19 @@ private: ExpressionAST *extractExpressionAST(Document::Ptr doc) const; Document::Ptr documentForExpression(const QString &expression) const; - void processEnvironment(CPlusPlus::Snapshot documents, - CPlusPlus::Document::Ptr doc, CPlusPlus::Environment *env, + void processEnvironment(Document::Ptr doc, Environment *env, QSet<QString> *processed) const; - QString preprocessedExpression(const QString &expression, - CPlusPlus::Snapshot documents, - CPlusPlus::Document::Ptr thisDocument) const; + QString preprocessedExpression(const QString &expression) const; +private: + Document::Ptr m_thisDocument; Snapshot m_snapshot; + QSharedPointer<CreateBindings> m_bindings; ExpressionAST *m_ast; - DeprecatedLookupContext m_lookupContext; + Symbol *m_lastVisibleSymbol; + LookupContext m_lookupContext; + mutable QSharedPointer<Environment> m_environment; }; } // namespace CPlusPlus diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index dad2cb3c1c821c17f3ba8418dad46643ac2393a7..454f889e23d904cd6cea8da7c9b0503bd0a15520 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -560,7 +560,7 @@ protected: } // end of anonymous namespace -static const QualifiedNameId *qualifiedNameIdForSymbol(Symbol *s, const DeprecatedLookupContext &context) +static const QualifiedNameId *qualifiedNameIdForSymbol(Symbol *s, Control *control) { const Name *symbolName = s->name(); if (! symbolName) @@ -591,7 +591,7 @@ static const QualifiedNameId *qualifiedNameIdForSymbol(Symbol *s, const Deprecat names.append(symbolName); } - return context.control()->qualifiedNameId(names.constData(), names.size()); + return control->qualifiedNameId(names.constData(), names.size()); } CPPEditorEditable::CPPEditorEditable(CPPEditor *editor) @@ -869,13 +869,12 @@ CPlusPlus::Symbol *CPPEditor::findCanonicalSymbol(const QTextCursor &cursor, // qDebug() << "code:" << code; TypeOfExpression typeOfExpression; - typeOfExpression.setSnapshot(snapshot); + typeOfExpression.init(doc, snapshot); Symbol *lastVisibleSymbol = doc->findSymbolAt(line, col); - const QList<LookupItem> results = typeOfExpression(code, doc, - lastVisibleSymbol, - TypeOfExpression::Preprocess); + const QList<LookupItem> results = typeOfExpression(code, lastVisibleSymbol, + TypeOfExpression::Preprocess); NamespaceBindingPtr glo = bind(doc, snapshot); Symbol *canonicalSymbol = DeprecatedLookupContext::canonicalSymbol(results, glo.data()); @@ -1255,13 +1254,10 @@ void CPPEditor::switchDeclarationDefinition() } if (f) { - TypeOfExpression typeOfExpression; - typeOfExpression.setSnapshot(m_modelManager->snapshot()); - QList<LookupItem> resolvedSymbols = typeOfExpression(QString(), doc, lastSymbol); - const DeprecatedLookupContext &context = typeOfExpression.lookupContext(); + LookupContext context(doc, snapshot); - const QualifiedNameId *q = qualifiedNameIdForSymbol(f, context); - QList<Symbol *> symbols = context.resolve(q); + const QualifiedNameId *q = qualifiedNameIdForSymbol(f, context.control()); + const QList<Symbol *> symbols = context.lookup(q, lastSymbol); // ### FIXME Symbol *declaration = 0; foreach (declaration, symbols) { @@ -1438,9 +1434,9 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor, const QString expression = expressionUnderCursor(tc); TypeOfExpression typeOfExpression; - typeOfExpression.setSnapshot(snapshot); + typeOfExpression.init(doc, snapshot); QList<LookupItem> resolvedSymbols = - typeOfExpression(expression, doc, lastSymbol); + typeOfExpression(expression, lastSymbol); if (!resolvedSymbols.isEmpty()) { LookupItem result = skipForwardDeclarations(resolvedSymbols); diff --git a/src/plugins/cppeditor/cpphoverhandler.cpp b/src/plugins/cppeditor/cpphoverhandler.cpp index 63be4f097fa2be1adbad5d40fe23aacc2ab71409..f38179e09edaffc684537edf0ca44100339c0318 100644 --- a/src/plugins/cppeditor/cpphoverhandler.cpp +++ b/src/plugins/cppeditor/cpphoverhandler.cpp @@ -180,7 +180,8 @@ static QString buildHelpId(Symbol *symbol, const Name *name) // ### move me static FullySpecifiedType resolve(const FullySpecifiedType &ty, - const DeprecatedLookupContext &context, + const LookupContext &context, + Symbol *lastVisibleSymbol, Symbol **resolvedSymbol, const Name **resolvedName) { @@ -188,22 +189,25 @@ static FullySpecifiedType resolve(const FullySpecifiedType &ty, if (const PointerType *ptrTy = ty->asPointerType()) { return control->pointerType(resolve(ptrTy->elementType(), context, + lastVisibleSymbol, resolvedSymbol, resolvedName)); } else if (const ReferenceType *refTy = ty->asReferenceType()) { return control->referenceType(resolve(refTy->elementType(), context, + lastVisibleSymbol, resolvedSymbol, resolvedName)); } else if (const PointerToMemberType *ptrToMemTy = ty->asPointerToMemberType()) { return control->pointerToMemberType(ptrToMemTy->memberName(), resolve(ptrToMemTy->elementType(), context, + lastVisibleSymbol, resolvedSymbol, resolvedName)); } else if (const NamedType *namedTy = ty->asNamedType()) { if (resolvedName) *resolvedName = namedTy->name(); - const QList<Symbol *> candidates = context.resolve(namedTy->name()); + const QList<Symbol *> candidates = context.lookup(namedTy->name(), lastVisibleSymbol); foreach (Symbol *c, candidates) { if (c->isClass() || c->isEnum()) { @@ -284,7 +288,7 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in Symbol *lastSymbol = doc->findSymbolAt(line, column); TypeOfExpression typeOfExpression; - typeOfExpression.setSnapshot(documents); + typeOfExpression.init(doc, documents); // We only want to show F1 if the tooltip matches the help id bool showF1 = true; @@ -332,7 +336,7 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in ExpressionUnderCursor expressionUnderCursor; const QString expression = expressionUnderCursor(tc); - const QList<LookupItem> types = typeOfExpression(expression, doc, lastSymbol); + const QList<LookupItem> types = typeOfExpression(expression, lastSymbol); if (!types.isEmpty()) { const LookupItem result = types.first(); @@ -343,6 +347,7 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in Symbol *resolvedSymbol = lookupSymbol; const Name *resolvedName = lookupSymbol ? lookupSymbol->name() : 0; firstType = resolve(firstType, typeOfExpression.lookupContext(), + lastSymbol, &resolvedSymbol, &resolvedName); if (resolvedSymbol && resolvedSymbol->scope() diff --git a/src/plugins/cppeditor/cppquickfix.cpp b/src/plugins/cppeditor/cppquickfix.cpp index bf295dcd0956efbdd8aa7cbbd403f8f9be1f5c07..5a7b97e87256ab71480e01de0f0820f5815ab952 100644 --- a/src/plugins/cppeditor/cppquickfix.cpp +++ b/src/plugins/cppeditor/cppquickfix.cpp @@ -1323,14 +1323,21 @@ void QuickFixOperation::apply() */ const QList<LookupItem> QuickFixOperation::typeOf(CPlusPlus::ExpressionAST *ast) { +#ifdef __GNUC__ +# warning port me +#endif + + qWarning() << Q_FUNC_INFO << __LINE__; + return QList<LookupItem>(); + +#if 0 unsigned line, column; document()->translationUnit()->getTokenStartPosition(ast->firstToken(), &line, &column); Symbol *lastVisibleSymbol = document()->findSymbolAt(line, column); - _lookupContext = DeprecatedLookupContext(lastVisibleSymbol, document(), document(), snapshot()); - - ResolveExpression resolveExpression(_lookupContext); + ResolveExpression resolveExpression(lastVisibleSymbol, _lookupContext); return resolveExpression(ast); +#endif } CPPQuickFixCollector::CPPQuickFixCollector() diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp index a5f583254cd18e97ed42fcaa3c0ab0402a2772a7..b47ebf403939d050461b010f3448a7384854f4e4 100644 --- a/src/plugins/cpptools/cppcodecompletion.cpp +++ b/src/plugins/cpptools/cppcodecompletion.cpp @@ -90,7 +90,7 @@ class FunctionArgumentWidget : public QLabel public: FunctionArgumentWidget(); void showFunctionHint(QList<Function *> functionSymbols, - const DeprecatedLookupContext &context, + const LookupContext &context, int startPosition); protected: @@ -118,7 +118,7 @@ private: QLabel *m_numberLabel; Utils::FakeToolTip *m_popupFrame; QList<Function *> m_items; - DeprecatedLookupContext m_context; + LookupContext m_context; }; class ConvertToCompletionItem: protected NameVisitor @@ -266,7 +266,7 @@ FunctionArgumentWidget::FunctionArgumentWidget(): } void FunctionArgumentWidget::showFunctionHint(QList<Function *> functionSymbols, - const DeprecatedLookupContext &context, + const LookupContext &context, int startPosition) { Q_ASSERT(!functionSymbols.isEmpty()); @@ -784,7 +784,7 @@ int CppCodeCompletion::startCompletionInternal(TextEditor::BaseTextEditor *edit, if (! thisDocument) return -1; - typeOfExpression.setSnapshot(snapshot); + typeOfExpression.init(thisDocument, snapshot); Symbol *lastVisibleSymbol = thisDocument->findSymbolAt(line, column); if (expression.isEmpty()) { @@ -798,14 +798,14 @@ int CppCodeCompletion::startCompletionInternal(TextEditor::BaseTextEditor *edit, } - QList<LookupItem> results = typeOfExpression(expression, thisDocument, lastVisibleSymbol, TypeOfExpression::Preprocess); - DeprecatedLookupContext context = typeOfExpression.lookupContext(); + QList<LookupItem> results = typeOfExpression(expression, lastVisibleSymbol, TypeOfExpression::Preprocess); + LookupContext context = typeOfExpression.lookupContext(); if (results.isEmpty()) { if (m_completionOperator == T_SIGNAL || m_completionOperator == T_SLOT) { if (! (expression.isEmpty() || expression == QLatin1String("this"))) { expression = QLatin1String("this"); - results = typeOfExpression(expression, thisDocument, lastVisibleSymbol); + results = typeOfExpression(expression, lastVisibleSymbol); } if (results.isEmpty()) @@ -828,8 +828,7 @@ int CppCodeCompletion::startCompletionInternal(TextEditor::BaseTextEditor *edit, // Resolve the type of this expression const QList<LookupItem> results = - typeOfExpression(baseExpression, thisDocument, - lastVisibleSymbol, + typeOfExpression(baseExpression, lastVisibleSymbol, TypeOfExpression::Preprocess); // If it's a class, add completions for the constructors @@ -908,7 +907,7 @@ int CppCodeCompletion::globalCompletion(Symbol *lastVisibleSymbol, } bool CppCodeCompletion::completeConstructorOrFunction(const QList<LookupItem> &results, - const DeprecatedLookupContext &context, + const LookupContext &context, int endOfExpression, bool toolTipOnly) { QList<Function *> functions; @@ -970,28 +969,19 @@ bool CppCodeCompletion::completeConstructorOrFunction(const QList<LookupItem> &r } if (functions.isEmpty()) { - ResolveExpression resolveExpression(context); - ResolveClass resolveClass; const Name *functionCallOp = context.control()->operatorNameId(OperatorNameId::FunctionCallOp); foreach (const LookupItem &result, results) { FullySpecifiedType ty = result.type().simplified(); + Symbol *lastVisibleSymbol = result.lastVisibleSymbol(); if (NamedType *namedTy = ty->asNamedType()) { - const QList<Symbol *> classObjectCandidates = resolveClass(namedTy->name(), result, context); + if (ClassOrNamespace *b = context.classOrNamespace(namedTy->name(), lastVisibleSymbol)) { + foreach (Symbol *overload, b->lookup(functionCallOp)) { + FullySpecifiedType overloadTy = overload->type().simplified(); - foreach (Symbol *classObjectCandidate, classObjectCandidates) { - if (Class *klass = classObjectCandidate->asClass()) { - const QList<LookupItem> overloads = - resolveExpression.resolveMember(functionCallOp, klass, - namedTy->name()); - - foreach (const LookupItem &overloadResult, overloads) { - FullySpecifiedType overloadTy = overloadResult.type().simplified(); - - if (Function *funTy = overloadTy->asFunctionType()) - functions.append(funTy); - } + if (Function *funTy = overloadTy->asFunctionType()) + functions.append(funTy); } } } @@ -1019,8 +1009,8 @@ bool CppCodeCompletion::completeConstructorOrFunction(const QList<LookupItem> &r // find a scope that encloses the current location, starting from the lastVisibileSymbol // and moving outwards Scope *sc = 0; - if (context.symbol()) - sc = context.symbol()->scope(); + if (typeOfExpression.lastVisibleSymbol()) + sc = typeOfExpression.lastVisibleSymbol()->scope(); else if (context.thisDocument()) sc = context.thisDocument()->globalSymbols(); @@ -1102,13 +1092,12 @@ bool CppCodeCompletion::completeConstructorOrFunction(const QList<LookupItem> &r } bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults, - const DeprecatedLookupContext &context) + const LookupContext &context) { if (baseResults.isEmpty()) return false; - ResolveExpression resolveExpression(context); - ResolveClass resolveClass; + ResolveExpression resolveExpression(typeOfExpression.lastVisibleSymbol(), context); bool replacedDotOperator = false; const QList<LookupItem> classObjectResults = @@ -1116,6 +1105,8 @@ bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults, m_completionOperator, &replacedDotOperator); + ClassOrNamespace *classOrNamespace = 0; + QList<Symbol *> classObjectCandidates; foreach (const LookupItem &r, classObjectResults) { FullySpecifiedType ty = r.type().simplified(); @@ -1124,17 +1115,19 @@ bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults, classObjectCandidates.append(klass); else if (NamedType *namedTy = ty->asNamedType()) { - const Name *className = namedTy->name(); - const QList<Symbol *> classes = resolveClass(className, r, context); + if (ClassOrNamespace *b = context.classOrNamespace(namedTy->name(), r.lastVisibleSymbol()->scope())) { + classOrNamespace = b; + break; + + } else { + Overview oo; - foreach (Symbol *c, classes) { - if (Class *klass = c->asClass()) - classObjectCandidates.append(klass); + qDebug() << "*** no class for" << oo(namedTy->name()); } } } - if (replacedDotOperator && ! classObjectCandidates.isEmpty()) { + if (replacedDotOperator && classOrNamespace) { // Replace . with -> int length = m_editor->position() - m_startPosition + 1; m_editor->setCurPos(m_startPosition - 1); @@ -1142,7 +1135,9 @@ bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults, ++m_startPosition; } - completeClass(classObjectCandidates, context, /*static lookup = */ false); + if (classOrNamespace) + completeClass(classOrNamespace, context, /*static lookup = */ false); + if (! m_completions.isEmpty()) return true; @@ -1150,17 +1145,11 @@ bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults, } bool CppCodeCompletion::completeScope(const QList<LookupItem> &results, - const DeprecatedLookupContext &deprecatedContext) + const LookupContext &context) { - 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(); @@ -1434,13 +1423,16 @@ void CppCodeCompletion::completeClass(const QList<Symbol *> &candidates, } bool CppCodeCompletion::completeQtMethod(const QList<LookupItem> &results, - const DeprecatedLookupContext &context, + const LookupContext &newContext, bool wantSignals) { if (results.isEmpty()) return false; - ResolveClass resolveClass; + DeprecatedLookupContext context(typeOfExpression.lastVisibleSymbol(), + newContext.expressionDocument(), + newContext.thisDocument(), + newContext.snapshot()); ConvertToCompletionItem toCompletionItem(this); Overview o; @@ -1461,8 +1453,11 @@ bool CppCodeCompletion::completeQtMethod(const QList<LookupItem> &results, if (! namedTy) // not a class name. continue; - const QList<Symbol *> classObjects = - resolveClass(namedTy->name(), p, context); + ClassOrNamespace *b = newContext.classOrNamespace(namedTy->name(), p.lastVisibleSymbol()); + if (! b) + continue; + + const QList<Symbol *> classObjects = b->symbols(); if (classObjects.isEmpty()) continue; @@ -1710,7 +1705,7 @@ void CppCodeCompletion::cleanup() // Set empty map in order to avoid referencing old versions of the documents // until the next completion - typeOfExpression.setSnapshot(Snapshot()); + typeOfExpression.reset(); } int CppCodeCompletion::findStartOfName(int pos) const diff --git a/src/plugins/cpptools/cppcodecompletion.h b/src/plugins/cpptools/cppcodecompletion.h index 76090459c538d5de19efba70b71e78affae55995..12f16687669dd7a77b04680ecef14089697305e3 100644 --- a/src/plugins/cpptools/cppcodecompletion.h +++ b/src/plugins/cpptools/cppcodecompletion.h @@ -114,14 +114,14 @@ private: const CPlusPlus::Snapshot &snapshot); bool completeConstructorOrFunction(const QList<CPlusPlus::LookupItem> &, - const CPlusPlus::DeprecatedLookupContext &, + const CPlusPlus::LookupContext &, int endOfExpression, bool toolTipOnly); bool completeMember(const QList<CPlusPlus::LookupItem> &, - const CPlusPlus::DeprecatedLookupContext &context); + const CPlusPlus::LookupContext &context); bool completeScope(const QList<CPlusPlus::LookupItem> &, - const CPlusPlus::DeprecatedLookupContext &context); + const CPlusPlus::LookupContext &context); void completeNamespace(CPlusPlus::ClassOrNamespace *binding, const CPlusPlus::LookupContext &context); @@ -139,16 +139,16 @@ private: bool completeConstructors(CPlusPlus::Class *klass); - bool completeQtMethod(const QList<CPlusPlus::LookupItem> &, - const CPlusPlus::DeprecatedLookupContext &context, + bool completeQtMethod(const QList<CPlusPlus::LookupItem> &context, + const CPlusPlus::LookupContext &context, bool wantSignals); bool completeSignal(const QList<CPlusPlus::LookupItem> &results, - const CPlusPlus::DeprecatedLookupContext &context) + const CPlusPlus::LookupContext &context) { return completeQtMethod(results, context, true); } bool completeSlot(const QList<CPlusPlus::LookupItem> &results, - const CPlusPlus::DeprecatedLookupContext &context) + const CPlusPlus::LookupContext &context) { return completeQtMethod(results, context, false); } int findStartOfName(int pos = -1) const;