Try to use the new LookupContext.

This commit is contained in:
Roberto Raggi
2010-05-05 12:06:38 +02:00
parent 66a9ef0725
commit d9527680a9
14 changed files with 325 additions and 446 deletions

View File

@@ -282,14 +282,14 @@ void FindUsages::checkExpression(unsigned startToken, unsigned endToken)
// qDebug() << "*** check expression:" << expression; // qDebug() << "*** check expression:" << expression;
TypeOfExpression typeofExpression; TypeOfExpression typeofExpression;
typeofExpression.setSnapshot(_snapshot); typeofExpression.init(_doc, _snapshot);
unsigned line, column; unsigned line, column;
getTokenStartPosition(startToken, &line, &column); getTokenStartPosition(startToken, &line, &column);
Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column); Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column);
const QList<LookupItem> results = typeofExpression(expression, _doc, lastVisibleSymbol, const QList<LookupItem> results = typeofExpression(expression, lastVisibleSymbol,
TypeOfExpression::Preprocess); TypeOfExpression::Preprocess);
QList<Symbol *> candidates; QList<Symbol *> candidates;

View File

@@ -47,10 +47,10 @@ namespace {
class ApplySubstitution class ApplySubstitution
{ {
public: public:
ApplySubstitution(const DeprecatedLookupContext &context, Symbol *symbol, const GenTemplateInstance::Substitution &substitution); ApplySubstitution(Control *control, Symbol *symbol, const GenTemplateInstance::Substitution &substitution);
~ApplySubstitution(); ~ApplySubstitution();
Control *control() const { return context.control(); } inline Control *control() const { return _control; }
FullySpecifiedType apply(const Name *name); FullySpecifiedType apply(const Name *name);
FullySpecifiedType apply(const FullySpecifiedType &type); FullySpecifiedType apply(const FullySpecifiedType &type);
@@ -309,16 +309,16 @@ private:
}; };
public: // attributes public: // attributes
DeprecatedLookupContext context; Control *_control;
Symbol *symbol; Symbol *symbol;
GenTemplateInstance::Substitution substitution; GenTemplateInstance::Substitution substitution;
ApplyToType applyToType; ApplyToType applyToType;
ApplyToName applyToName; ApplyToName applyToName;
}; };
ApplySubstitution::ApplySubstitution(const DeprecatedLookupContext &context, Symbol *symbol, ApplySubstitution::ApplySubstitution(Control *control, Symbol *symbol,
const GenTemplateInstance::Substitution &substitution) const GenTemplateInstance::Substitution &substitution)
: context(context), symbol(symbol), : _control(control), symbol(symbol),
substitution(substitution), substitution(substitution),
applyToType(this), applyToName(this) applyToType(this), applyToName(this)
{ } { }
@@ -363,17 +363,17 @@ FullySpecifiedType ApplySubstitution::applySubstitution(int index) const
} // end of anonymous namespace } // end of anonymous namespace
GenTemplateInstance::GenTemplateInstance(const DeprecatedLookupContext &context, const Substitution &substitution) GenTemplateInstance::GenTemplateInstance(Control *control, const Substitution &substitution)
: _symbol(0), : _symbol(0),
_context(context), _control(control),
_substitution(substitution) _substitution(substitution)
{ } { }
FullySpecifiedType GenTemplateInstance::operator()(Symbol *symbol) FullySpecifiedType GenTemplateInstance::operator()(Symbol *symbol)
{ {
ApplySubstitution o(_context, symbol, _substitution); ApplySubstitution o(_control, symbol, _substitution);
return o.apply(symbol->type()); return o.apply(symbol->type());
} }
Control *GenTemplateInstance::control() const Control *GenTemplateInstance::control() const
{ return _context.control(); } { return _control; }

View File

@@ -47,7 +47,7 @@ public:
typedef QList< QPair<const Identifier *, FullySpecifiedType> > Substitution; typedef QList< QPair<const Identifier *, FullySpecifiedType> > Substitution;
public: public:
GenTemplateInstance(const DeprecatedLookupContext &context, const Substitution &substitution); GenTemplateInstance(Control *control, const Substitution &substitution);
FullySpecifiedType operator()(Symbol *symbol); FullySpecifiedType operator()(Symbol *symbol);
@@ -55,7 +55,7 @@ public:
private: private:
Symbol *_symbol; Symbol *_symbol;
DeprecatedLookupContext _context; Control *_control;
const Substitution _substitution; const Substitution _substitution;
}; };

View File

@@ -148,6 +148,16 @@ ClassOrNamespace *LookupContext::classOrNamespace(const Name *name, Symbol *last
return classOrNamespace(name, lastVisibleSymbol); 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 *> LookupContext::lookup(const Name *name, Scope *scope) const
{ {
QList<Symbol *> candidates; QList<Symbol *> candidates;
@@ -168,19 +178,15 @@ QList<Symbol *> LookupContext::lookup(const Name *name, Scope *scope) const
Symbol *member = scope->symbolAt(index); Symbol *member = scope->symbolAt(index);
if (UsingNamespaceDirective *u = member->asUsingNamespaceDirective()) { if (UsingNamespaceDirective *u = member->asUsingNamespaceDirective()) {
Namespace *enclosingNamespace = u->enclosingNamespaceScope()->owner()->asNamespace(); if (Namespace *enclosingNamespace = u->enclosingNamespaceScope()->owner()->asNamespace()) {
//qDebug() << "*** enclosing namespace:" << enclosingNamespace; if (ClassOrNamespace *b = bindings()->findClassOrNamespace(enclosingNamespace)) {
Q_ASSERT(enclosingNamespace != 0); if (ClassOrNamespace *uu = b->lookupClassOrNamespace(u->name())) {
candidates = uu->lookup(name);
ClassOrNamespace *b = bindings()->findClassOrNamespace(enclosingNamespace); if (! candidates.isEmpty())
//qDebug() << "**** binding:" << b; return candidates;
Q_ASSERT(b != 0); }
}
if (ClassOrNamespace *uu = b->lookupClassOrNamespace(u->name())) {
candidates = uu->lookup(name);
if (! candidates.isEmpty())
return candidates;
} }
} }
} }

View File

@@ -174,6 +174,7 @@ public:
Document::Ptr document(const QString &fileName) const; Document::Ptr document(const QString &fileName) const;
Snapshot snapshot() const; Snapshot snapshot() const;
QList<Symbol *> lookup(const Name *name, Symbol *lastVisibleSymbol) const;
QList<Symbol *> lookup(const Name *name, Scope *scope) const; QList<Symbol *> lookup(const Name *name, Scope *scope) const;
ClassOrNamespace *globalNamespace() const; ClassOrNamespace *globalNamespace() const;
@@ -188,7 +189,7 @@ public:
/// \internal /// \internal
void setBindings(QSharedPointer<CreateBindings> bindings); void setBindings(QSharedPointer<CreateBindings> bindings);
Q_DECL_DEPRECATED Control *control() const; Control *control() const; // ### deprecate
private: private:
Control *_control; Control *_control;

View File

@@ -28,7 +28,7 @@
**************************************************************************/ **************************************************************************/
#include "ResolveExpression.h" #include "ResolveExpression.h"
#include "DeprecatedLookupContext.h" #include "LookupContext.h"
#include "Overview.h" #include "Overview.h"
#include "GenTemplateInstance.h" #include "GenTemplateInstance.h"
@@ -43,7 +43,6 @@
#include <NameVisitor.h> #include <NameVisitor.h>
#include <QtCore/QList> #include <QtCore/QList>
#include <QtCore/QVarLengthArray>
#include <QtCore/QtDebug> #include <QtCore/QtDebug>
using namespace CPlusPlus; using namespace CPlusPlus;
@@ -71,8 +70,21 @@ static QList<_Tp> removeDuplicates(const QList<_Tp> &results)
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
// ResolveExpression // ResolveExpression
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
ResolveExpression::ResolveExpression(const DeprecatedLookupContext &context) ResolveExpression::ResolveExpression(Symbol *lastVisibleSymbol, const LookupContext &context)
: ASTVisitor(context.expressionDocument()->translationUnit()), : 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), _context(context),
sem(context.expressionDocument()->translationUnit()) sem(context.expressionDocument()->translationUnit())
{ } { }
@@ -102,22 +114,26 @@ void ResolveExpression::addResults(const QList<LookupItem> &results)
} }
void ResolveExpression::addResult(const FullySpecifiedType &ty, Symbol *symbol) void ResolveExpression::addResult(const FullySpecifiedType &ty, Symbol *symbol)
{ return addResult(LookupItem(ty, symbol)); } {
if (! symbol) {
if (_scope)
symbol = _scope->owner();
else
symbol = _context.thisDocument()->globalNamespace();
}
return addResult(LookupItem(ty, symbol));
}
void ResolveExpression::addResult(const LookupItem &r) void ResolveExpression::addResult(const LookupItem &r)
{ {
LookupItem p = r; Q_ASSERT(r.lastVisibleSymbol() != 0);
if (! p.lastVisibleSymbol()) if (! _results.contains(r))
p.setLastVisibleSymbol(_context.symbol()); _results.append(r);
if (! _results.contains(p))
_results.append(p);
} }
QList<Scope *> ResolveExpression::visibleScopes(const LookupItem &result) const
{ return _context.visibleScopes(result); }
bool ResolveExpression::visit(BinaryExpressionAST *ast) bool ResolveExpression::visit(BinaryExpressionAST *ast)
{ {
if (tokenKind(ast->binary_op_token) == T_COMMA && ast->right_expression && ast->right_expression->asQtMethod() != 0) { if (tokenKind(ast->binary_op_token) == T_COMMA && ast->right_expression && ast->right_expression->asQtMethod() != 0) {
@@ -289,10 +305,7 @@ bool ResolveExpression::visit(ThisExpressionAST *)
void ResolveExpression::thisObject() void ResolveExpression::thisObject()
{ {
if (! _context.symbol()) Scope *scope = _scope;
return;
Scope *scope = _context.symbol()->scope();
for (; scope; scope = scope->enclosingScope()) { for (; scope; scope = scope->enclosingScope()) {
if (scope->isFunctionScope()) { if (scope->isFunctionScope()) {
Function *fun = scope->owner()->asFunction(); Function *fun = scope->owner()->asFunction();
@@ -387,42 +400,28 @@ bool ResolveExpression::visit(CompoundLiteralAST *ast)
bool ResolveExpression::visit(QualifiedNameAST *ast) bool ResolveExpression::visit(QualifiedNameAST *ast)
{ {
ResolveClass resolveClass; if (const Name *name = ast->name) {
const Name *name = ast->name; const QList<Symbol *> candidates = _context.lookup(name, _scope);
QList<Symbol *> symbols = _context.resolve(name); foreach (Symbol *candidate, candidates)
foreach (Symbol *symbol, symbols) { addResult(candidate->type(), candidate);
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);
} }
return false;
}
bool ResolveExpression::visit(OperatorFunctionIdAST *)
{
return false;
}
bool ResolveExpression::visit(ConversionFunctionIdAST *)
{
return false; return false;
} }
bool ResolveExpression::visit(SimpleNameAST *ast) bool ResolveExpression::visit(SimpleNameAST *ast)
{ {
QList<Symbol *> symbols = _context.resolve(ast->name); QList<Symbol *> symbols = _context.lookup(ast->name, _scope);
foreach (Symbol *symbol, symbols)
addResult(symbol->type(), symbol);
return false;
}
bool ResolveExpression::visit(TemplateIdAST *ast)
{
const QList<Symbol *> symbols = _context.lookup(ast->name, _scope);
foreach (Symbol *symbol, symbols) foreach (Symbol *symbol, symbols)
addResult(symbol->type(), symbol); addResult(symbol->type(), symbol);
@@ -436,12 +435,13 @@ bool ResolveExpression::visit(DestructorNameAST *)
return false; return false;
} }
bool ResolveExpression::visit(TemplateIdAST *ast) bool ResolveExpression::visit(OperatorFunctionIdAST *)
{ {
QList<Symbol *> symbols = _context.resolve(ast->name); return false;
foreach (Symbol *symbol, symbols) }
addResult(symbol->type(), symbol);
bool ResolveExpression::visit(ConversionFunctionIdAST *)
{
return false; return false;
} }
@@ -470,8 +470,6 @@ bool ResolveExpression::maybeValidPrototype(Function *funTy, unsigned actualArgu
bool ResolveExpression::visit(CallAST *ast) bool ResolveExpression::visit(CallAST *ast)
{ {
ResolveClass resolveClass;
const QList<LookupItem> baseResults = _results; const QList<LookupItem> baseResults = _results;
_results.clear(); _results.clear();
@@ -491,17 +489,13 @@ bool ResolveExpression::visit(CallAST *ast)
Symbol *lastVisibleSymbol = result.lastVisibleSymbol(); Symbol *lastVisibleSymbol = result.lastVisibleSymbol();
if (NamedType *namedTy = ty->asNamedType()) { if (NamedType *namedTy = ty->asNamedType()) {
const QList<Symbol *> classObjectCandidates = resolveClass(namedTy->name(), result, _context); if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), lastVisibleSymbol->scope())) {
foreach (Symbol *overload, b->lookup(functionCallOp)) {
foreach (Symbol *classObject, classObjectCandidates) { if (Function *funTy = overload->type()->asFunctionType()) {
const QList<LookupItem> overloads = resolveMember(functionCallOp, classObject->asClass(), namedTy->name()); if (maybeValidPrototype(funTy, actualArgumentCount)) {
Function *proto = instantiate(namedTy->name(), funTy)->asFunctionType();
foreach (const LookupItem &o, overloads) { addResult(proto->returnType().simplified(), lastVisibleSymbol);
FullySpecifiedType overloadTy = o.type().simplified(); }
if (Function *funTy = overloadTy->asFunctionType()) {
if (maybeValidPrototype(funTy, actualArgumentCount))
addResult(funTy->returnType().simplified(), lastVisibleSymbol);
} }
} }
} }
@@ -526,37 +520,29 @@ bool ResolveExpression::visit(ArrayAccessAST *ast)
_results.clear(); _results.clear();
const QList<LookupItem> indexResults = operator()(ast->expression); const QList<LookupItem> indexResults = operator()(ast->expression);
ResolveClass resolveClass;
const Name *arrayAccessOp = control()->operatorNameId(OperatorNameId::ArrayAccessOp); const Name *arrayAccessOp = control()->operatorNameId(OperatorNameId::ArrayAccessOp);
foreach (const LookupItem &result, baseResults) { foreach (const LookupItem &result, baseResults) {
FullySpecifiedType ty = result.type().simplified(); FullySpecifiedType ty = result.type().simplified();
Symbol *contextSymbol = result.lastVisibleSymbol(); Symbol *lastVisibleSymbol = result.lastVisibleSymbol();
if (PointerType *ptrTy = ty->asPointerType()) { if (PointerType *ptrTy = ty->asPointerType()) {
addResult(ptrTy->elementType().simplified(), contextSymbol); addResult(ptrTy->elementType().simplified(), lastVisibleSymbol);
} else if (ArrayType *arrTy = ty->asArrayType()) { } else if (ArrayType *arrTy = ty->asArrayType()) {
addResult(arrTy->elementType().simplified(), contextSymbol); addResult(arrTy->elementType().simplified(), lastVisibleSymbol);
} else if (NamedType *namedTy = ty->asNamedType()) { } else if (NamedType *namedTy = ty->asNamedType()) {
const QList<Symbol *> classObjectCandidates = if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), lastVisibleSymbol->scope())) {
resolveClass(namedTy->name(), result, _context); foreach (Symbol *overload, b->lookup(arrayAccessOp)) {
if (Function *funTy = overload->type()->asFunctionType()) {
foreach (Symbol *classObject, classObjectCandidates) { Function *proto = instantiate(namedTy->name(), funTy)->asFunctionType();
Q_ASSERT(classObject->isClass()); // ### TODO: check the actual arguments
addResult(proto->returnType().simplified(), lastVisibleSymbol);
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);
} }
} }
} }
} }
} }
@@ -567,7 +553,7 @@ bool ResolveExpression::visit(MemberAccessAST *ast)
{ {
// The candidate types for the base expression are stored in // The candidate types for the base expression are stored in
// _results. // _results.
QList<LookupItem> baseResults = _results; const QList<LookupItem> baseResults = _results;
// Evaluate the expression-id that follows the access operator. // Evaluate the expression-id that follows the access operator.
const Name *memberName = 0; const Name *memberName = 0;
@@ -601,56 +587,23 @@ ResolveExpression::resolveBaseExpression(const QList<LookupItem> &baseResults, i
} }
if (accessOp == T_ARROW) { 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()) { if (NamedType *namedTy = ty->asNamedType()) {
ResolveClass resolveClass;
const Name *arrowAccessOp = control()->operatorNameId(OperatorNameId::ArrowOp); const Name *arrowAccessOp = control()->operatorNameId(OperatorNameId::ArrowOp);
const QList<Symbol *> candidates = resolveClass(namedTy->name(), result, _context);
foreach (Symbol *classObject, candidates) { if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), result.lastVisibleSymbol()->scope())) {
const QList<LookupItem> overloads = resolveMember(arrowAccessOp, classObject->asClass(), foreach (Symbol *overload, b->lookup(arrowAccessOp)) {
namedTy->name()); if (Function *funTy = overload->type()->asFunctionType()) {
FullySpecifiedType f = instantiate(namedTy->name(), funTy);
FullySpecifiedType retTy = f->asFunctionType()->returnType().simplified();
foreach (const LookupItem &r, overloads) { if (PointerType *ptrTy = retTy->asPointerType()) {
FullySpecifiedType typeOfOverloadFunction = r.type().simplified(); FullySpecifiedType elementTy = ptrTy->elementType().simplified();
Symbol *lastVisibleSymbol = r.lastVisibleSymbol(); results.append(LookupItem(elementTy, overload));
Function *funTy = typeOfOverloadFunction->asFunctionType(); }
if (! funTy)
continue;
typeOfOverloadFunction = funTy->returnType().simplified();
if (PointerType *ptrTy = typeOfOverloadFunction->asPointerType()) {
FullySpecifiedType elementTy = ptrTy->elementType().simplified();
if (elementTy->isNamedType())
results.append(LookupItem(elementTy, lastVisibleSymbol));
} }
} }
} }
} else if (PointerType *ptrTy = ty->asPointerType()) { } else if (PointerType *ptrTy = ty->asPointerType()) {
FullySpecifiedType elementTy = ptrTy->elementType().simplified(); FullySpecifiedType elementTy = ptrTy->elementType().simplified();
@@ -669,8 +622,7 @@ ResolveExpression::resolveBaseExpression(const QList<LookupItem> &baseResults, i
} }
if (NamedType *namedTy = ty->asNamedType()) { if (NamedType *namedTy = ty->asNamedType()) {
const QList<Scope *> visibleScopes = _context.visibleScopes(result); const QList<Symbol *> candidates = _context.lookup(namedTy->name(), result.lastVisibleSymbol());
const QList<Symbol *> candidates = _context.resolve(namedTy->name(), visibleScopes);
foreach (Symbol *candidate, candidates) { foreach (Symbol *candidate, candidates) {
if (candidate->isTypedef() && candidate->type()->isNamedType()) { if (candidate->isTypedef() && candidate->type()->isNamedType()) {
ty = candidate->type(); ty = candidate->type();
@@ -704,10 +656,10 @@ ResolveExpression::resolveMemberExpression(const QList<LookupItem> &baseResults,
const Name *memberName, const Name *memberName,
bool *replacedDotOperator) const bool *replacedDotOperator) const
{ {
ResolveClass resolveClass;
QList<LookupItem> results; QList<LookupItem> results;
const QList<LookupItem> classObjectResults = resolveBaseExpression(baseResults, accessOp, replacedDotOperator); const QList<LookupItem> classObjectResults = resolveBaseExpression(baseResults, accessOp, replacedDotOperator);
foreach (const LookupItem &r, classObjectResults) { foreach (const LookupItem &r, classObjectResults) {
FullySpecifiedType ty = r.type(); FullySpecifiedType ty = r.type();
@@ -715,12 +667,9 @@ ResolveExpression::resolveMemberExpression(const QList<LookupItem> &baseResults,
results += resolveMember(memberName, klass); results += resolveMember(memberName, klass);
else if (NamedType *namedTy = ty->asNamedType()) { else if (NamedType *namedTy = ty->asNamedType()) {
const Name *className = namedTy->name(); if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), r.lastVisibleSymbol()->scope())) {
const QList<Symbol *> classes = resolveClass(className, r, _context); foreach (Symbol *c, b->lookup(memberName))
results.append(LookupItem(instantiate(namedTy->name(), c), c));
foreach (Symbol *c, classes) {
if (Class *klass = c->asClass())
results += resolveMember(memberName, klass, className);
} }
} }
} }
@@ -728,22 +677,49 @@ ResolveExpression::resolveMemberExpression(const QList<LookupItem> &baseResults,
return removeDuplicates(results); 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> QList<LookupItem>
ResolveExpression::resolveMember(const Name *memberName, Class *klass, ResolveExpression::resolveMember(const Name *memberName, Class *klass,
const Name *className) const const Name *className) const
{ {
QList<LookupItem> results; QList<LookupItem> results;
if (! klass)
return results;
if (! className) if (! className)
className = klass->name(); className = klass->name();
if (! className) if (! className)
return results; return results;
QList<Scope *> scopes; const QList<Symbol *> candidates = _context.lookup(memberName, klass->members());
_context.expand(klass->members(), _context.visibleScopes(), &scopes);
const QList<Symbol *> candidates = _context.resolve(memberName, scopes);
foreach (Symbol *candidate, candidates) { foreach (Symbol *candidate, candidates) {
FullySpecifiedType ty = candidate->type(); 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); ty = inst(candidate);
} }
@@ -782,14 +758,10 @@ QList<LookupItem>
ResolveExpression::resolveMember(const Name *memberName, ObjCClass *klass) const ResolveExpression::resolveMember(const Name *memberName, ObjCClass *klass) const
{ {
QList<LookupItem> results; QList<LookupItem> results;
if (!memberName || !klass) if (!memberName || !klass)
return results; return results;
QList<Scope *> scopes; const QList<Symbol *> candidates = _context.lookup(memberName, klass->members());
_context.expand(klass->members(), _context.visibleScopes(), &scopes);
QList<Symbol *> candidates = _context.resolve(memberName, scopes);
foreach (Symbol *candidate, candidates) { foreach (Symbol *candidate, candidates) {
FullySpecifiedType ty = candidate->type(); FullySpecifiedType ty = candidate->type();
@@ -828,8 +800,7 @@ bool ResolveExpression::visit(ObjCMessageExpressionAST *ast)
} }
if (klassName&&ast->selector && ast->selector->name) { if (klassName&&ast->selector && ast->selector->name) {
ResolveObjCClass resolveObjCClass; const QList<Symbol *> resolvedSymbols = _context.lookup(klassName, result.lastVisibleSymbol());
QList<Symbol *> resolvedSymbols = resolveObjCClass(klassName, result, _context);
foreach (Symbol *resolvedSymbol, resolvedSymbols) foreach (Symbol *resolvedSymbol, resolvedSymbols)
if (ObjCClass *klass = resolvedSymbol->asObjCClass()) if (ObjCClass *klass = resolvedSymbol->asObjCClass())
_results.append(resolveMember(ast->selector->name, klass)); _results.append(resolveMember(ast->selector->name, klass));
@@ -839,103 +810,3 @@ bool ResolveExpression::visit(ObjCMessageExpressionAST *ast)
return false; 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;
}

View File

@@ -30,7 +30,7 @@
#ifndef CPLUSPLUS_RESOLVEEXPRESSION_H #ifndef CPLUSPLUS_RESOLVEEXPRESSION_H
#define CPLUSPLUS_RESOLVEEXPRESSION_H #define CPLUSPLUS_RESOLVEEXPRESSION_H
#include "DeprecatedLookupContext.h" #include "LookupContext.h"
#include <ASTVisitor.h> #include <ASTVisitor.h>
#include <Semantic.h> #include <Semantic.h>
@@ -41,27 +41,30 @@ namespace CPlusPlus {
class CPLUSPLUS_EXPORT ResolveExpression: protected ASTVisitor class CPLUSPLUS_EXPORT ResolveExpression: protected ASTVisitor
{ {
public: public:
ResolveExpression(const DeprecatedLookupContext &context); ResolveExpression(Symbol *lastVisibleSymbol, const LookupContext &context);
ResolveExpression(Scope *scope, const LookupContext &context);
virtual ~ResolveExpression(); virtual ~ResolveExpression();
QList<LookupItem> operator()(ExpressionAST *ast); QList<LookupItem> operator()(ExpressionAST *ast);
QList<LookupItem> resolveMemberExpression(const QList<LookupItem> &baseResults, QList<LookupItem> resolveMemberExpression(const QList<LookupItem> &baseResults,
unsigned accessOp, unsigned accessOp,
const Name *memberName, const Name *memberName,
bool *replacedDotOperator = 0) const; bool *replacedDotOperator = 0) const;
QList<LookupItem> resolveBaseExpression(const QList<LookupItem> &baseResults, QList<LookupItem> resolveBaseExpression(const QList<LookupItem> &baseResults,
int accessOp, int accessOp,
bool *replacedDotOperator = 0) const; bool *replacedDotOperator = 0) const;
QList<LookupItem> resolveMember(const Name *memberName, Class *klass, Q_DECL_DEPRECATED QList<LookupItem> resolveMember(const Name *memberName, Class *klass,
const Name *className = 0) const; 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: protected:
QList<LookupItem> switchResults(const QList<LookupItem> &symbols); QList<LookupItem> switchResults(const QList<LookupItem> &symbols);
FullySpecifiedType instantiate(const Name *className, Symbol *candidate) const;
void thisObject(); void thisObject();
void addResult(const FullySpecifiedType &ty, Symbol *symbol = 0); void addResult(const FullySpecifiedType &ty, Symbol *symbol = 0);
@@ -113,44 +116,15 @@ protected:
// Objective-C expressions // Objective-C expressions
virtual bool visit(ObjCMessageExpressionAST *ast); virtual bool visit(ObjCMessageExpressionAST *ast);
QList<Scope *> visibleScopes(const LookupItem &result) const;
private: private:
DeprecatedLookupContext _context; Symbol *_lastVisibleSymbol;
Scope *_scope;
LookupContext _context;
Semantic sem; Semantic sem;
QList<LookupItem> _results; QList<LookupItem> _results;
Symbol *_declSymbol; 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 } // end of namespace CPlusPlus
#endif // CPLUSPLUS_RESOLVEEXPRESSION_H #endif // CPLUSPLUS_RESOLVEEXPRESSION_H

View File

@@ -29,7 +29,7 @@
#include "TypeOfExpression.h" #include "TypeOfExpression.h"
#include <TranslationUnit.h> #include <TranslationUnit.h>
#include "DeprecatedLookupContext.h" #include "LookupContext.h"
#include "ResolveExpression.h" #include "ResolveExpression.h"
#include "pp.h" #include "pp.h"
@@ -39,44 +39,59 @@
using namespace CPlusPlus; using namespace CPlusPlus;
TypeOfExpression::TypeOfExpression(): 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_thisDocument = thisDocument;
m_lookupContext = DeprecatedLookupContext(); 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, QList<LookupItem> TypeOfExpression::operator()(const QString &expression,
Document::Ptr document, Symbol *lastVisibleSymbol,
Symbol *lastVisibleSymbol, PreprocessMode mode)
PreprocessMode mode)
{ {
QString code = expression; QString code = expression;
if (mode == Preprocess) if (mode == Preprocess)
code = preprocessedExpression(expression, m_snapshot, document); code = preprocessedExpression(expression);
Document::Ptr expressionDoc = documentForExpression(code); Document::Ptr expressionDoc = documentForExpression(code);
expressionDoc->check(); expressionDoc->check();
m_ast = extractExpressionAST(expressionDoc); m_ast = extractExpressionAST(expressionDoc);
m_lookupContext = DeprecatedLookupContext(lastVisibleSymbol, expressionDoc, m_lastVisibleSymbol = lastVisibleSymbol;
document, m_snapshot);
ResolveExpression resolveExpression(m_lookupContext); m_lookupContext = LookupContext(expressionDoc, m_thisDocument, m_snapshot);
m_lookupContext.setBindings(m_bindings);
ResolveExpression resolveExpression(lastVisibleSymbol, m_lookupContext);
return resolveExpression(m_ast); return resolveExpression(m_ast);
} }
QString TypeOfExpression::preprocess(const QString &expression, QString TypeOfExpression::preprocess(const QString &expression) const
Document::Ptr document) const
{ {
return preprocessedExpression(expression, m_snapshot, document); return preprocessedExpression(expression);
} }
ExpressionAST *TypeOfExpression::ast() const ExpressionAST *TypeOfExpression::ast() const
@@ -84,7 +99,12 @@ ExpressionAST *TypeOfExpression::ast() const
return m_ast; return m_ast;
} }
const DeprecatedLookupContext &TypeOfExpression::lookupContext() const Symbol *TypeOfExpression::lastVisibleSymbol() const
{
return m_lastVisibleSymbol;
}
const LookupContext &TypeOfExpression::lookupContext() const
{ {
return m_lookupContext; return m_lookupContext;
} }
@@ -112,37 +132,35 @@ Document::Ptr TypeOfExpression::documentForExpression(const QString &expression)
return doc; return doc;
} }
void TypeOfExpression::processEnvironment(Snapshot documents, void TypeOfExpression::processEnvironment(Document::Ptr doc, Environment *env,
Document::Ptr doc, Environment *env,
QSet<QString> *processed) const QSet<QString> *processed) const
{ {
if (! doc) if (doc && ! processed->contains(doc->fileName())) {
return; processed->insert(doc->fileName());
if (processed->contains(doc->fileName()))
return; foreach (const Document::Include &incl, doc->includes())
processed->insert(doc->fileName()); processEnvironment(m_snapshot.document(incl.fileName()), env, processed);
foreach (const Document::Include &incl, doc->includes()) {
processEnvironment(documents, foreach (const Macro &macro, doc->definedMacros())
documents.document(incl.fileName()), env->bind(macro);
env, processed);
} }
foreach (const Macro &macro, doc->definedMacros())
env->bind(macro);
} }
QString TypeOfExpression::preprocessedExpression(const QString &expression, QString TypeOfExpression::preprocessedExpression(const QString &expression) const
Snapshot documents,
Document::Ptr thisDocument) const
{ {
if (expression.trimmed().isEmpty()) if (expression.trimmed().isEmpty())
return expression; return expression;
Environment env; if (! m_environment) {
QSet<QString> processed; Environment *env = new Environment(); // ### cache the environment.
processEnvironment(documents, thisDocument,
&env, &processed); QSet<QString> processed;
processEnvironment(m_thisDocument, env, &processed);
m_environment = QSharedPointer<Environment>(env);
}
const QByteArray code = expression.toUtf8(); const QByteArray code = expression.toUtf8();
Preprocessor preproc(0, &env); Preprocessor preproc(0, m_environment.data());
const QByteArray preprocessedCode = preproc("<expression>", code); const QByteArray preprocessedCode = preproc("<expression>", code);
return QString::fromUtf8(preprocessedCode.constData(), preprocessedCode.size()); return QString::fromUtf8(preprocessedCode.constData(), preprocessedCode.size());
} }

View File

@@ -30,7 +30,8 @@
#define CPLUSPLUS_TYPEOFEXPRESSION_H #define CPLUSPLUS_TYPEOFEXPRESSION_H
#include "CppDocument.h" #include "CppDocument.h"
#include "DeprecatedLookupContext.h" #include "LookupContext.h"
#include "PreprocessorEnvironment.h"
#include <ASTfwd.h> #include <ASTfwd.h>
#include <QtCore/QMap> #include <QtCore/QMap>
@@ -44,11 +45,11 @@ class Macro;
class CPLUSPLUS_EXPORT TypeOfExpression class CPLUSPLUS_EXPORT TypeOfExpression
{ {
Q_DISABLE_COPY(TypeOfExpression)
public: public:
TypeOfExpression(); TypeOfExpression();
Snapshot snapshot() const;
/** /**
* Sets the documents used to evaluate expressions. Should be set before * Sets the documents used to evaluate expressions. Should be set before
* calling this functor. * calling this functor.
@@ -56,7 +57,10 @@ public:
* Also clears the lookup context, so can be used to make sure references * Also clears the lookup context, so can be used to make sure references
* to the documents previously used are removed. * 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 { enum PreprocessMode {
NoPreprocess, NoPreprocess,
@@ -72,14 +76,13 @@ public:
* has been made! * has been made!
* *
* @param expression The expression to evaluate. * @param expression The expression to evaluate.
* @param document The document the expression is part of.
* @param lastVisibleSymbol The last visible symbol in the document. * @param lastVisibleSymbol The last visible symbol in the document.
*/ */
QList<LookupItem> operator()(const QString &expression, Document::Ptr document, QList<LookupItem> operator()(const QString &expression,
Symbol *lastVisibleSymbol, Symbol *lastVisibleSymbol,
PreprocessMode mode = NoPreprocess); 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. * Returns the AST of the last evaluated expression.
@@ -89,7 +92,8 @@ public:
/** /**
* Returns the lookup context of the last evaluated expression. * Returns the lookup context of the last evaluated expression.
*/ */
const DeprecatedLookupContext &lookupContext() const; const LookupContext &lookupContext() const;
Symbol *lastVisibleSymbol() const;
ExpressionAST *expressionAST() const; ExpressionAST *expressionAST() const;
@@ -97,17 +101,19 @@ private:
ExpressionAST *extractExpressionAST(Document::Ptr doc) const; ExpressionAST *extractExpressionAST(Document::Ptr doc) const;
Document::Ptr documentForExpression(const QString &expression) const; Document::Ptr documentForExpression(const QString &expression) const;
void processEnvironment(CPlusPlus::Snapshot documents, void processEnvironment(Document::Ptr doc, Environment *env,
CPlusPlus::Document::Ptr doc, CPlusPlus::Environment *env,
QSet<QString> *processed) const; QSet<QString> *processed) const;
QString preprocessedExpression(const QString &expression, QString preprocessedExpression(const QString &expression) const;
CPlusPlus::Snapshot documents,
CPlusPlus::Document::Ptr thisDocument) const;
private:
Document::Ptr m_thisDocument;
Snapshot m_snapshot; Snapshot m_snapshot;
QSharedPointer<CreateBindings> m_bindings;
ExpressionAST *m_ast; ExpressionAST *m_ast;
DeprecatedLookupContext m_lookupContext; Symbol *m_lastVisibleSymbol;
LookupContext m_lookupContext;
mutable QSharedPointer<Environment> m_environment;
}; };
} // namespace CPlusPlus } // namespace CPlusPlus

View File

@@ -560,7 +560,7 @@ protected:
} // end of anonymous namespace } // 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(); const Name *symbolName = s->name();
if (! symbolName) if (! symbolName)
@@ -591,7 +591,7 @@ static const QualifiedNameId *qualifiedNameIdForSymbol(Symbol *s, const Deprecat
names.append(symbolName); names.append(symbolName);
} }
return context.control()->qualifiedNameId(names.constData(), names.size()); return control->qualifiedNameId(names.constData(), names.size());
} }
CPPEditorEditable::CPPEditorEditable(CPPEditor *editor) CPPEditorEditable::CPPEditorEditable(CPPEditor *editor)
@@ -869,13 +869,12 @@ CPlusPlus::Symbol *CPPEditor::findCanonicalSymbol(const QTextCursor &cursor,
// qDebug() << "code:" << code; // qDebug() << "code:" << code;
TypeOfExpression typeOfExpression; TypeOfExpression typeOfExpression;
typeOfExpression.setSnapshot(snapshot); typeOfExpression.init(doc, snapshot);
Symbol *lastVisibleSymbol = doc->findSymbolAt(line, col); Symbol *lastVisibleSymbol = doc->findSymbolAt(line, col);
const QList<LookupItem> results = typeOfExpression(code, doc, const QList<LookupItem> results = typeOfExpression(code, lastVisibleSymbol,
lastVisibleSymbol, TypeOfExpression::Preprocess);
TypeOfExpression::Preprocess);
NamespaceBindingPtr glo = bind(doc, snapshot); NamespaceBindingPtr glo = bind(doc, snapshot);
Symbol *canonicalSymbol = DeprecatedLookupContext::canonicalSymbol(results, glo.data()); Symbol *canonicalSymbol = DeprecatedLookupContext::canonicalSymbol(results, glo.data());
@@ -1255,13 +1254,10 @@ void CPPEditor::switchDeclarationDefinition()
} }
if (f) { if (f) {
TypeOfExpression typeOfExpression; LookupContext context(doc, snapshot);
typeOfExpression.setSnapshot(m_modelManager->snapshot());
QList<LookupItem> resolvedSymbols = typeOfExpression(QString(), doc, lastSymbol);
const DeprecatedLookupContext &context = typeOfExpression.lookupContext();
const QualifiedNameId *q = qualifiedNameIdForSymbol(f, context); const QualifiedNameId *q = qualifiedNameIdForSymbol(f, context.control());
QList<Symbol *> symbols = context.resolve(q); const QList<Symbol *> symbols = context.lookup(q, lastSymbol); // ### FIXME
Symbol *declaration = 0; Symbol *declaration = 0;
foreach (declaration, symbols) { foreach (declaration, symbols) {
@@ -1438,9 +1434,9 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
const QString expression = expressionUnderCursor(tc); const QString expression = expressionUnderCursor(tc);
TypeOfExpression typeOfExpression; TypeOfExpression typeOfExpression;
typeOfExpression.setSnapshot(snapshot); typeOfExpression.init(doc, snapshot);
QList<LookupItem> resolvedSymbols = QList<LookupItem> resolvedSymbols =
typeOfExpression(expression, doc, lastSymbol); typeOfExpression(expression, lastSymbol);
if (!resolvedSymbols.isEmpty()) { if (!resolvedSymbols.isEmpty()) {
LookupItem result = skipForwardDeclarations(resolvedSymbols); LookupItem result = skipForwardDeclarations(resolvedSymbols);

View File

@@ -180,7 +180,8 @@ static QString buildHelpId(Symbol *symbol, const Name *name)
// ### move me // ### move me
static FullySpecifiedType resolve(const FullySpecifiedType &ty, static FullySpecifiedType resolve(const FullySpecifiedType &ty,
const DeprecatedLookupContext &context, const LookupContext &context,
Symbol *lastVisibleSymbol,
Symbol **resolvedSymbol, Symbol **resolvedSymbol,
const Name **resolvedName) const Name **resolvedName)
{ {
@@ -188,22 +189,25 @@ static FullySpecifiedType resolve(const FullySpecifiedType &ty,
if (const PointerType *ptrTy = ty->asPointerType()) { if (const PointerType *ptrTy = ty->asPointerType()) {
return control->pointerType(resolve(ptrTy->elementType(), context, return control->pointerType(resolve(ptrTy->elementType(), context,
lastVisibleSymbol,
resolvedSymbol, resolvedName)); resolvedSymbol, resolvedName));
} else if (const ReferenceType *refTy = ty->asReferenceType()) { } else if (const ReferenceType *refTy = ty->asReferenceType()) {
return control->referenceType(resolve(refTy->elementType(), context, return control->referenceType(resolve(refTy->elementType(), context,
lastVisibleSymbol,
resolvedSymbol, resolvedName)); resolvedSymbol, resolvedName));
} else if (const PointerToMemberType *ptrToMemTy = ty->asPointerToMemberType()) { } else if (const PointerToMemberType *ptrToMemTy = ty->asPointerToMemberType()) {
return control->pointerToMemberType(ptrToMemTy->memberName(), return control->pointerToMemberType(ptrToMemTy->memberName(),
resolve(ptrToMemTy->elementType(), context, resolve(ptrToMemTy->elementType(), context,
lastVisibleSymbol,
resolvedSymbol, resolvedName)); resolvedSymbol, resolvedName));
} else if (const NamedType *namedTy = ty->asNamedType()) { } else if (const NamedType *namedTy = ty->asNamedType()) {
if (resolvedName) if (resolvedName)
*resolvedName = namedTy->name(); *resolvedName = namedTy->name();
const QList<Symbol *> candidates = context.resolve(namedTy->name()); const QList<Symbol *> candidates = context.lookup(namedTy->name(), lastVisibleSymbol);
foreach (Symbol *c, candidates) { foreach (Symbol *c, candidates) {
if (c->isClass() || c->isEnum()) { if (c->isClass() || c->isEnum()) {
@@ -284,7 +288,7 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
Symbol *lastSymbol = doc->findSymbolAt(line, column); Symbol *lastSymbol = doc->findSymbolAt(line, column);
TypeOfExpression typeOfExpression; TypeOfExpression typeOfExpression;
typeOfExpression.setSnapshot(documents); typeOfExpression.init(doc, documents);
// We only want to show F1 if the tooltip matches the help id // We only want to show F1 if the tooltip matches the help id
bool showF1 = true; bool showF1 = true;
@@ -332,7 +336,7 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
ExpressionUnderCursor expressionUnderCursor; ExpressionUnderCursor expressionUnderCursor;
const QString expression = expressionUnderCursor(tc); const QString expression = expressionUnderCursor(tc);
const QList<LookupItem> types = typeOfExpression(expression, doc, lastSymbol); const QList<LookupItem> types = typeOfExpression(expression, lastSymbol);
if (!types.isEmpty()) { if (!types.isEmpty()) {
const LookupItem result = types.first(); const LookupItem result = types.first();
@@ -343,6 +347,7 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
Symbol *resolvedSymbol = lookupSymbol; Symbol *resolvedSymbol = lookupSymbol;
const Name *resolvedName = lookupSymbol ? lookupSymbol->name() : 0; const Name *resolvedName = lookupSymbol ? lookupSymbol->name() : 0;
firstType = resolve(firstType, typeOfExpression.lookupContext(), firstType = resolve(firstType, typeOfExpression.lookupContext(),
lastSymbol,
&resolvedSymbol, &resolvedName); &resolvedSymbol, &resolvedName);
if (resolvedSymbol && resolvedSymbol->scope() if (resolvedSymbol && resolvedSymbol->scope()

View File

@@ -1323,14 +1323,21 @@ void QuickFixOperation::apply()
*/ */
const QList<LookupItem> QuickFixOperation::typeOf(CPlusPlus::ExpressionAST *ast) 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; unsigned line, column;
document()->translationUnit()->getTokenStartPosition(ast->firstToken(), &line, &column); document()->translationUnit()->getTokenStartPosition(ast->firstToken(), &line, &column);
Symbol *lastVisibleSymbol = document()->findSymbolAt(line, column); Symbol *lastVisibleSymbol = document()->findSymbolAt(line, column);
_lookupContext = DeprecatedLookupContext(lastVisibleSymbol, document(), document(), snapshot()); ResolveExpression resolveExpression(lastVisibleSymbol, _lookupContext);
ResolveExpression resolveExpression(_lookupContext);
return resolveExpression(ast); return resolveExpression(ast);
#endif
} }
CPPQuickFixCollector::CPPQuickFixCollector() CPPQuickFixCollector::CPPQuickFixCollector()

View File

@@ -90,7 +90,7 @@ class FunctionArgumentWidget : public QLabel
public: public:
FunctionArgumentWidget(); FunctionArgumentWidget();
void showFunctionHint(QList<Function *> functionSymbols, void showFunctionHint(QList<Function *> functionSymbols,
const DeprecatedLookupContext &context, const LookupContext &context,
int startPosition); int startPosition);
protected: protected:
@@ -118,7 +118,7 @@ private:
QLabel *m_numberLabel; QLabel *m_numberLabel;
Utils::FakeToolTip *m_popupFrame; Utils::FakeToolTip *m_popupFrame;
QList<Function *> m_items; QList<Function *> m_items;
DeprecatedLookupContext m_context; LookupContext m_context;
}; };
class ConvertToCompletionItem: protected NameVisitor class ConvertToCompletionItem: protected NameVisitor
@@ -266,7 +266,7 @@ FunctionArgumentWidget::FunctionArgumentWidget():
} }
void FunctionArgumentWidget::showFunctionHint(QList<Function *> functionSymbols, void FunctionArgumentWidget::showFunctionHint(QList<Function *> functionSymbols,
const DeprecatedLookupContext &context, const LookupContext &context,
int startPosition) int startPosition)
{ {
Q_ASSERT(!functionSymbols.isEmpty()); Q_ASSERT(!functionSymbols.isEmpty());
@@ -784,7 +784,7 @@ int CppCodeCompletion::startCompletionInternal(TextEditor::BaseTextEditor *edit,
if (! thisDocument) if (! thisDocument)
return -1; return -1;
typeOfExpression.setSnapshot(snapshot); typeOfExpression.init(thisDocument, snapshot);
Symbol *lastVisibleSymbol = thisDocument->findSymbolAt(line, column); Symbol *lastVisibleSymbol = thisDocument->findSymbolAt(line, column);
if (expression.isEmpty()) { if (expression.isEmpty()) {
@@ -798,14 +798,14 @@ int CppCodeCompletion::startCompletionInternal(TextEditor::BaseTextEditor *edit,
} }
QList<LookupItem> results = typeOfExpression(expression, thisDocument, lastVisibleSymbol, TypeOfExpression::Preprocess); QList<LookupItem> results = typeOfExpression(expression, lastVisibleSymbol, TypeOfExpression::Preprocess);
DeprecatedLookupContext context = typeOfExpression.lookupContext(); LookupContext context = typeOfExpression.lookupContext();
if (results.isEmpty()) { if (results.isEmpty()) {
if (m_completionOperator == T_SIGNAL || m_completionOperator == T_SLOT) { if (m_completionOperator == T_SIGNAL || m_completionOperator == T_SLOT) {
if (! (expression.isEmpty() || expression == QLatin1String("this"))) { if (! (expression.isEmpty() || expression == QLatin1String("this"))) {
expression = QLatin1String("this"); expression = QLatin1String("this");
results = typeOfExpression(expression, thisDocument, lastVisibleSymbol); results = typeOfExpression(expression, lastVisibleSymbol);
} }
if (results.isEmpty()) if (results.isEmpty())
@@ -828,8 +828,7 @@ int CppCodeCompletion::startCompletionInternal(TextEditor::BaseTextEditor *edit,
// Resolve the type of this expression // Resolve the type of this expression
const QList<LookupItem> results = const QList<LookupItem> results =
typeOfExpression(baseExpression, thisDocument, typeOfExpression(baseExpression, lastVisibleSymbol,
lastVisibleSymbol,
TypeOfExpression::Preprocess); TypeOfExpression::Preprocess);
// If it's a class, add completions for the constructors // 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, bool CppCodeCompletion::completeConstructorOrFunction(const QList<LookupItem> &results,
const DeprecatedLookupContext &context, const LookupContext &context,
int endOfExpression, bool toolTipOnly) int endOfExpression, bool toolTipOnly)
{ {
QList<Function *> functions; QList<Function *> functions;
@@ -970,28 +969,19 @@ bool CppCodeCompletion::completeConstructorOrFunction(const QList<LookupItem> &r
} }
if (functions.isEmpty()) { if (functions.isEmpty()) {
ResolveExpression resolveExpression(context);
ResolveClass resolveClass;
const Name *functionCallOp = context.control()->operatorNameId(OperatorNameId::FunctionCallOp); const Name *functionCallOp = context.control()->operatorNameId(OperatorNameId::FunctionCallOp);
foreach (const LookupItem &result, results) { foreach (const LookupItem &result, results) {
FullySpecifiedType ty = result.type().simplified(); FullySpecifiedType ty = result.type().simplified();
Symbol *lastVisibleSymbol = result.lastVisibleSymbol();
if (NamedType *namedTy = ty->asNamedType()) { 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 (Function *funTy = overloadTy->asFunctionType())
if (Class *klass = classObjectCandidate->asClass()) { functions.append(funTy);
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);
}
} }
} }
} }
@@ -1019,8 +1009,8 @@ bool CppCodeCompletion::completeConstructorOrFunction(const QList<LookupItem> &r
// find a scope that encloses the current location, starting from the lastVisibileSymbol // find a scope that encloses the current location, starting from the lastVisibileSymbol
// and moving outwards // and moving outwards
Scope *sc = 0; Scope *sc = 0;
if (context.symbol()) if (typeOfExpression.lastVisibleSymbol())
sc = context.symbol()->scope(); sc = typeOfExpression.lastVisibleSymbol()->scope();
else if (context.thisDocument()) else if (context.thisDocument())
sc = context.thisDocument()->globalSymbols(); sc = context.thisDocument()->globalSymbols();
@@ -1102,13 +1092,12 @@ bool CppCodeCompletion::completeConstructorOrFunction(const QList<LookupItem> &r
} }
bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults, bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults,
const DeprecatedLookupContext &context) const LookupContext &context)
{ {
if (baseResults.isEmpty()) if (baseResults.isEmpty())
return false; return false;
ResolveExpression resolveExpression(context); ResolveExpression resolveExpression(typeOfExpression.lastVisibleSymbol(), context);
ResolveClass resolveClass;
bool replacedDotOperator = false; bool replacedDotOperator = false;
const QList<LookupItem> classObjectResults = const QList<LookupItem> classObjectResults =
@@ -1116,6 +1105,8 @@ bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults,
m_completionOperator, m_completionOperator,
&replacedDotOperator); &replacedDotOperator);
ClassOrNamespace *classOrNamespace = 0;
QList<Symbol *> classObjectCandidates; QList<Symbol *> classObjectCandidates;
foreach (const LookupItem &r, classObjectResults) { foreach (const LookupItem &r, classObjectResults) {
FullySpecifiedType ty = r.type().simplified(); FullySpecifiedType ty = r.type().simplified();
@@ -1124,17 +1115,19 @@ bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults,
classObjectCandidates.append(klass); classObjectCandidates.append(klass);
else if (NamedType *namedTy = ty->asNamedType()) { else if (NamedType *namedTy = ty->asNamedType()) {
const Name *className = namedTy->name(); if (ClassOrNamespace *b = context.classOrNamespace(namedTy->name(), r.lastVisibleSymbol()->scope())) {
const QList<Symbol *> classes = resolveClass(className, r, context); classOrNamespace = b;
break;
foreach (Symbol *c, classes) { } else {
if (Class *klass = c->asClass()) Overview oo;
classObjectCandidates.append(klass);
qDebug() << "*** no class for" << oo(namedTy->name());
} }
} }
} }
if (replacedDotOperator && ! classObjectCandidates.isEmpty()) { if (replacedDotOperator && classOrNamespace) {
// Replace . with -> // Replace . with ->
int length = m_editor->position() - m_startPosition + 1; int length = m_editor->position() - m_startPosition + 1;
m_editor->setCurPos(m_startPosition - 1); m_editor->setCurPos(m_startPosition - 1);
@@ -1142,7 +1135,9 @@ bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults,
++m_startPosition; ++m_startPosition;
} }
completeClass(classObjectCandidates, context, /*static lookup = */ false); if (classOrNamespace)
completeClass(classOrNamespace, context, /*static lookup = */ false);
if (! m_completions.isEmpty()) if (! m_completions.isEmpty())
return true; return true;
@@ -1150,17 +1145,11 @@ bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults,
} }
bool CppCodeCompletion::completeScope(const QList<LookupItem> &results, bool CppCodeCompletion::completeScope(const QList<LookupItem> &results,
const DeprecatedLookupContext &deprecatedContext) const LookupContext &context)
{ {
qDebug() << Q_FUNC_INFO;
if (results.isEmpty()) if (results.isEmpty())
return false; return false;
LookupContext context(deprecatedContext.expressionDocument(),
deprecatedContext.thisDocument(),
deprecatedContext.snapshot());
foreach (const LookupItem &result, results) { foreach (const LookupItem &result, results) {
FullySpecifiedType ty = result.type(); FullySpecifiedType ty = result.type();
Symbol *lastVisibleSymbol = result.lastVisibleSymbol(); Symbol *lastVisibleSymbol = result.lastVisibleSymbol();
@@ -1434,13 +1423,16 @@ void CppCodeCompletion::completeClass(const QList<Symbol *> &candidates,
} }
bool CppCodeCompletion::completeQtMethod(const QList<LookupItem> &results, bool CppCodeCompletion::completeQtMethod(const QList<LookupItem> &results,
const DeprecatedLookupContext &context, const LookupContext &newContext,
bool wantSignals) bool wantSignals)
{ {
if (results.isEmpty()) if (results.isEmpty())
return false; return false;
ResolveClass resolveClass; DeprecatedLookupContext context(typeOfExpression.lastVisibleSymbol(),
newContext.expressionDocument(),
newContext.thisDocument(),
newContext.snapshot());
ConvertToCompletionItem toCompletionItem(this); ConvertToCompletionItem toCompletionItem(this);
Overview o; Overview o;
@@ -1461,8 +1453,11 @@ bool CppCodeCompletion::completeQtMethod(const QList<LookupItem> &results,
if (! namedTy) // not a class name. if (! namedTy) // not a class name.
continue; continue;
const QList<Symbol *> classObjects = ClassOrNamespace *b = newContext.classOrNamespace(namedTy->name(), p.lastVisibleSymbol());
resolveClass(namedTy->name(), p, context); if (! b)
continue;
const QList<Symbol *> classObjects = b->symbols();
if (classObjects.isEmpty()) if (classObjects.isEmpty())
continue; continue;
@@ -1710,7 +1705,7 @@ void CppCodeCompletion::cleanup()
// Set empty map in order to avoid referencing old versions of the documents // Set empty map in order to avoid referencing old versions of the documents
// until the next completion // until the next completion
typeOfExpression.setSnapshot(Snapshot()); typeOfExpression.reset();
} }
int CppCodeCompletion::findStartOfName(int pos) const int CppCodeCompletion::findStartOfName(int pos) const

View File

@@ -114,14 +114,14 @@ private:
const CPlusPlus::Snapshot &snapshot); const CPlusPlus::Snapshot &snapshot);
bool completeConstructorOrFunction(const QList<CPlusPlus::LookupItem> &, bool completeConstructorOrFunction(const QList<CPlusPlus::LookupItem> &,
const CPlusPlus::DeprecatedLookupContext &, const CPlusPlus::LookupContext &,
int endOfExpression, bool toolTipOnly); int endOfExpression, bool toolTipOnly);
bool completeMember(const QList<CPlusPlus::LookupItem> &, bool completeMember(const QList<CPlusPlus::LookupItem> &,
const CPlusPlus::DeprecatedLookupContext &context); const CPlusPlus::LookupContext &context);
bool completeScope(const QList<CPlusPlus::LookupItem> &, bool completeScope(const QList<CPlusPlus::LookupItem> &,
const CPlusPlus::DeprecatedLookupContext &context); const CPlusPlus::LookupContext &context);
void completeNamespace(CPlusPlus::ClassOrNamespace *binding, void completeNamespace(CPlusPlus::ClassOrNamespace *binding,
const CPlusPlus::LookupContext &context); const CPlusPlus::LookupContext &context);
@@ -139,16 +139,16 @@ private:
bool completeConstructors(CPlusPlus::Class *klass); bool completeConstructors(CPlusPlus::Class *klass);
bool completeQtMethod(const QList<CPlusPlus::LookupItem> &, bool completeQtMethod(const QList<CPlusPlus::LookupItem> &context,
const CPlusPlus::DeprecatedLookupContext &context, const CPlusPlus::LookupContext &context,
bool wantSignals); bool wantSignals);
bool completeSignal(const QList<CPlusPlus::LookupItem> &results, bool completeSignal(const QList<CPlusPlus::LookupItem> &results,
const CPlusPlus::DeprecatedLookupContext &context) const CPlusPlus::LookupContext &context)
{ return completeQtMethod(results, context, true); } { return completeQtMethod(results, context, true); }
bool completeSlot(const QList<CPlusPlus::LookupItem> &results, bool completeSlot(const QList<CPlusPlus::LookupItem> &results,
const CPlusPlus::DeprecatedLookupContext &context) const CPlusPlus::LookupContext &context)
{ return completeQtMethod(results, context, false); } { return completeQtMethod(results, context, false); }
int findStartOfName(int pos = -1) const; int findStartOfName(int pos = -1) const;