forked from qt-creator/qt-creator
		
	Improved LookupItem and get rid of some deprecated code.
This commit is contained in:
		| @@ -57,6 +57,91 @@ using namespace CPlusPlus; | ||||
|  | ||||
| namespace { | ||||
|  | ||||
| class FindScopeAt: protected SymbolVisitor | ||||
| { | ||||
|     TranslationUnit *_unit; | ||||
|     unsigned _line; | ||||
|     unsigned _column; | ||||
|     Scope *_scope; | ||||
|  | ||||
| public: | ||||
|     FindScopeAt(TranslationUnit *unit, unsigned line, unsigned column) | ||||
|         : _unit(unit), _line(line), _column(column), _scope(0) {} | ||||
|  | ||||
|     Scope *operator()(Symbol *symbol) | ||||
|     { | ||||
|         accept(symbol); | ||||
|         return _scope; | ||||
|     } | ||||
|  | ||||
| protected: | ||||
|     bool process(ScopedSymbol *symbol) | ||||
|     { | ||||
|         if (! _scope) { | ||||
|             Scope *scope = symbol->members(); | ||||
|  | ||||
|             for (unsigned i = 0; i < scope->symbolCount(); ++i) { | ||||
|                 accept(scope->symbolAt(i)); | ||||
|  | ||||
|                 if (_scope) | ||||
|                     return false; | ||||
|             } | ||||
|  | ||||
|             unsigned startLine, startColumn; | ||||
|             _unit->getPosition(symbol->startOffset(), &startLine, &startColumn); | ||||
|  | ||||
|             if (_line > startLine || (_line == startLine && _column >= startColumn)) { | ||||
|                 unsigned endLine, endColumn; | ||||
|                 _unit->getPosition(symbol->endOffset(), &endLine, &endColumn); | ||||
|  | ||||
|                 if (_line < endLine || (_line == endLine && _column < endColumn)) | ||||
|                     _scope = scope; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     using SymbolVisitor::visit; | ||||
|  | ||||
|     virtual bool preVisit(Symbol *) | ||||
|     { return ! _scope; } | ||||
|  | ||||
|     virtual bool visit(UsingNamespaceDirective *) { return false; } | ||||
|     virtual bool visit(UsingDeclaration *) { return false; } | ||||
|     virtual bool visit(NamespaceAlias *) { return false; } | ||||
|     virtual bool visit(Declaration *) { return false; } | ||||
|     virtual bool visit(Argument *) { return false; } | ||||
|     virtual bool visit(TypenameArgument *) { return false; } | ||||
|     virtual bool visit(BaseClass *) { return false; } | ||||
|     virtual bool visit(ForwardClassDeclaration *) { return false; } | ||||
|  | ||||
|     virtual bool visit(Enum *symbol) | ||||
|     { return process(symbol); } | ||||
|  | ||||
|     virtual bool visit(Function *symbol) | ||||
|     { return process(symbol); } | ||||
|  | ||||
|     virtual bool visit(Namespace *symbol) | ||||
|     { return process(symbol); } | ||||
|  | ||||
|     virtual bool visit(Class *symbol) | ||||
|     { return process(symbol); } | ||||
|  | ||||
|     virtual bool visit(Block *symbol) | ||||
|     { return process(symbol); } | ||||
|  | ||||
|     // Objective-C | ||||
|     virtual bool visit(ObjCBaseClass *) { return false; } | ||||
|     virtual bool visit(ObjCBaseProtocol *) { return false; } | ||||
|     virtual bool visit(ObjCClass *) { return false; } | ||||
|     virtual bool visit(ObjCForwardClassDeclaration *) { return false; } | ||||
|     virtual bool visit(ObjCProtocol *) { return false; } | ||||
|     virtual bool visit(ObjCForwardProtocolDeclaration *) { return false; } | ||||
|     virtual bool visit(ObjCMethod *) { return false; } | ||||
|     virtual bool visit(ObjCPropertyDeclaration *) { return false; } | ||||
| }; | ||||
|  | ||||
| class DocumentDiagnosticClient : public DiagnosticClient | ||||
| { | ||||
|     enum { MAX_MESSAGE_COUNT = 10 }; | ||||
| @@ -313,6 +398,12 @@ void Document::setGlobalNamespace(Namespace *globalNamespace) | ||||
|     _globalNamespace = globalNamespace; | ||||
| } | ||||
|  | ||||
| Scope *Document::scopeAt(unsigned line, unsigned column) | ||||
| { | ||||
|     FindScopeAt findScopeAt(_translationUnit, line, column); | ||||
|     return findScopeAt(_globalNamespace); | ||||
| } | ||||
|  | ||||
| Symbol *Document::findSymbolAt(unsigned line, unsigned column) const | ||||
| { | ||||
|     return findSymbolAt(line, column, globalSymbols()); | ||||
| @@ -616,7 +707,7 @@ Symbol *Snapshot::findMatchingDefinition(Symbol *symbol) const | ||||
|     } | ||||
|  | ||||
|     LookupContext thisContext(thisDocument, *this); | ||||
|     const QList<Symbol *> declarationCandidates = thisContext.lookup(symbol->name(), symbol); | ||||
|     const QList<Symbol *> declarationCandidates = thisContext.lookup(symbol->name(), symbol->scope()); | ||||
|     if (declarationCandidates.isEmpty()) { | ||||
|         qWarning() << "unresolved declaration:" << symbol->fileName() << symbol->line() << symbol->column(); | ||||
|         return 0; | ||||
| @@ -644,7 +735,7 @@ Symbol *Snapshot::findMatchingDefinition(Symbol *symbol) const | ||||
|             QList<Function *> viableFunctions; | ||||
|  | ||||
|             foreach (Function *fun, result) { | ||||
|                 const QList<Symbol *> declarations = context.lookup(fun->name(), fun); | ||||
|                 const QList<Symbol *> declarations = context.lookup(fun->name(), fun->scope()); | ||||
|  | ||||
|                 if (declarations.contains(declaration)) | ||||
|                     viableFunctions.append(fun); | ||||
|   | ||||
| @@ -92,7 +92,8 @@ public: | ||||
|     QList<Macro> definedMacros() const | ||||
|     { return _definedMacros; } | ||||
|  | ||||
|     Symbol *findSymbolAt(unsigned line, unsigned column) const; | ||||
|     Q_DECL_DEPRECATED Symbol *findSymbolAt(unsigned line, unsigned column) const; | ||||
|     Scope *scopeAt(unsigned line, unsigned column); | ||||
|  | ||||
|     QByteArray source() const; | ||||
|     void setSource(const QByteArray &source); | ||||
|   | ||||
| @@ -349,7 +349,7 @@ QList<Scope *> DeprecatedLookupContext::buildVisibleScopes() | ||||
| } | ||||
|  | ||||
| QList<Scope *> DeprecatedLookupContext::visibleScopes(const LookupItem &result) const | ||||
| { return visibleScopes(result.lastVisibleSymbol()); } | ||||
| { return visibleScopes(result.declaration()); } | ||||
|  | ||||
| QList<Scope *> DeprecatedLookupContext::visibleScopes(Symbol *symbol) const | ||||
| { | ||||
| @@ -710,7 +710,7 @@ Symbol *DeprecatedLookupContext::canonicalSymbol(const QList<LookupItem> &result | ||||
|     QList<Symbol *> candidates; | ||||
|  | ||||
|     foreach (const LookupItem &result, results) | ||||
|         candidates.append(result.lastVisibleSymbol()); // ### not exactly. | ||||
|         candidates.append(result.declaration()); // ### not exactly. | ||||
|  | ||||
|     return canonicalSymbol(candidates, globalNamespaceBinding); | ||||
| } | ||||
|   | ||||
| @@ -29,6 +29,7 @@ | ||||
|  | ||||
| #include "FindUsages.h" | ||||
| #include "TypeOfExpression.h" | ||||
| #include "DeprecatedLookupContext.h" | ||||
|  | ||||
| #include <Control.h> | ||||
| #include <Literals.h> | ||||
| @@ -46,6 +47,7 @@ FindUsages::FindUsages(Document::Ptr doc, const Snapshot &snapshot) | ||||
|     : ASTVisitor(doc->translationUnit()), | ||||
|       _doc(doc), | ||||
|       _snapshot(snapshot), | ||||
|       _context(doc, snapshot), | ||||
|       _source(_doc->source()), | ||||
|       _sem(doc->translationUnit()), | ||||
|       _inSimpleDeclaration(0), | ||||
| @@ -105,6 +107,14 @@ QString FindUsages::matchingLine(const Token &tk) const | ||||
|     return matchingLine; | ||||
| } | ||||
|  | ||||
| Scope *FindUsages::scopeAt(unsigned tokenIndex) const | ||||
| { | ||||
|     TranslationUnit *unit = _doc->translationUnit(); | ||||
|     unsigned line, column; | ||||
|     unit->getTokenPosition(tokenIndex, &line, &column); | ||||
|     return _doc->scopeAt(line, column); | ||||
| } | ||||
|  | ||||
| void FindUsages::reportResult(unsigned tokenIndex, const QList<Symbol *> &candidates) | ||||
| { | ||||
|     if (_processed.contains(tokenIndex)) | ||||
| @@ -201,27 +211,6 @@ bool FindUsages::checkSymbol(Symbol *symbol) const | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| DeprecatedLookupContext FindUsages::currentContext(AST *ast) | ||||
| { | ||||
|     unsigned line, column; | ||||
|     getTokenStartPosition(ast->firstToken(), &line, &column); | ||||
|     Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column); | ||||
|  | ||||
|     if (_inQProperty && lastVisibleSymbol->isClass()) { | ||||
|         Scope *memberScope = lastVisibleSymbol->asClass()->members(); | ||||
|  | ||||
|         if (unsigned count = memberScope->symbolCount()) | ||||
|             lastVisibleSymbol = memberScope->symbolAt(count - 1); | ||||
|     } | ||||
|  | ||||
|     if (lastVisibleSymbol && lastVisibleSymbol == _previousContext.symbol()) | ||||
|         return _previousContext; | ||||
|  | ||||
|     DeprecatedLookupContext ctx(lastVisibleSymbol, _exprDoc, _doc, _snapshot); | ||||
|     _previousContext = ctx; | ||||
|     return _previousContext; | ||||
| } | ||||
|  | ||||
| void FindUsages::ensureNameIsValid(NameAST *ast) | ||||
| { | ||||
|     if (ast && ! ast->name) | ||||
| @@ -235,8 +224,7 @@ bool FindUsages::visit(MemInitializerAST *ast) | ||||
|  | ||||
|         SimpleNameAST *simple = ast->name->asSimpleName(); | ||||
|         if (identifier(simple->identifier_token) == _id) { | ||||
|             DeprecatedLookupContext context = currentContext(ast); | ||||
|             const QList<Symbol *> candidates = context.resolve(simple->name); | ||||
|             const QList<Symbol *> candidates = _context.lookup(simple->name, scopeAt(simple->identifier_token)); | ||||
|             reportResult(simple->identifier_token, candidates); | ||||
|         } | ||||
|     } | ||||
| @@ -286,15 +274,15 @@ void FindUsages::checkExpression(unsigned startToken, unsigned endToken) | ||||
|  | ||||
|     unsigned line, column; | ||||
|     getTokenStartPosition(startToken, &line, &column); | ||||
|     Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column); | ||||
|     Scope *scope = _doc->scopeAt(line, column); | ||||
|  | ||||
|     const QList<LookupItem> results = typeofExpression(expression, lastVisibleSymbol, | ||||
|     const QList<LookupItem> results = typeofExpression(expression, scope, | ||||
|                                                        TypeOfExpression::Preprocess); | ||||
|  | ||||
|     QList<Symbol *> candidates; | ||||
|  | ||||
|     foreach (const LookupItem &r, results) { | ||||
|         Symbol *lastVisibleSymbol = r.lastVisibleSymbol(); | ||||
|         Symbol *lastVisibleSymbol = r.declaration(); | ||||
|         candidates.append(lastVisibleSymbol); | ||||
|     } | ||||
|  | ||||
| @@ -365,8 +353,7 @@ bool FindUsages::visit(EnumeratorAST *ast) | ||||
| { | ||||
|     const Identifier *id = identifier(ast->identifier_token); | ||||
|     if (id == _id) { | ||||
|         DeprecatedLookupContext context = currentContext(ast); | ||||
|         const QList<Symbol *> candidates = context.resolve(control()->nameId(id)); | ||||
|         const QList<Symbol *> candidates = _context.lookup(control()->nameId(id), scopeAt(ast->identifier_token)); | ||||
|         reportResult(ast->identifier_token, candidates); | ||||
|     } | ||||
|  | ||||
| @@ -379,8 +366,7 @@ bool FindUsages::visit(SimpleNameAST *ast) | ||||
| { | ||||
|     const Identifier *id = identifier(ast->identifier_token); | ||||
|     if (id == _id) { | ||||
|         DeprecatedLookupContext context = currentContext(ast); | ||||
|         const QList<Symbol *> candidates = context.resolve(ast->name); | ||||
|         const QList<Symbol *> candidates = _context.lookup(ast->name, scopeAt(ast->identifier_token)); | ||||
|         reportResult(ast->identifier_token, candidates); | ||||
|     } | ||||
|  | ||||
| @@ -391,8 +377,7 @@ bool FindUsages::visit(DestructorNameAST *ast) | ||||
| { | ||||
|     const Identifier *id = identifier(ast->identifier_token); | ||||
|     if (id == _id) { | ||||
|         DeprecatedLookupContext context = currentContext(ast); | ||||
|         const QList<Symbol *> candidates = context.resolve(ast->name); | ||||
|         const QList<Symbol *> candidates = _context.lookup(ast->name, scopeAt(ast->identifier_token)); | ||||
|         reportResult(ast->identifier_token, candidates); | ||||
|     } | ||||
|  | ||||
| @@ -402,8 +387,7 @@ bool FindUsages::visit(DestructorNameAST *ast) | ||||
| bool FindUsages::visit(TemplateIdAST *ast) | ||||
| { | ||||
|     if (_id == identifier(ast->identifier_token)) { | ||||
|         DeprecatedLookupContext context = currentContext(ast); | ||||
|         const QList<Symbol *> candidates = context.resolve(ast->name); | ||||
|         const QList<Symbol *> candidates = _context.lookup(ast->name, scopeAt(ast->identifier_token)); | ||||
|         reportResult(ast->identifier_token, candidates); | ||||
|     } | ||||
|  | ||||
| @@ -478,8 +462,7 @@ bool FindUsages::visit(ObjCSelectorAST *ast) | ||||
|     if (ast->name) { | ||||
|         const Identifier *id = ast->name->identifier(); | ||||
|         if (id == _id) { | ||||
|             DeprecatedLookupContext context = currentContext(ast); | ||||
|             const QList<Symbol *> candidates = context.resolve(ast->name); | ||||
|             const QList<Symbol *> candidates = _context.lookup(ast->name, scopeAt(ast->firstToken())); | ||||
|             reportResult(ast->firstToken(), candidates); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -30,7 +30,7 @@ | ||||
| #ifndef FINDUSAGES_H | ||||
| #define FINDUSAGES_H | ||||
|  | ||||
| #include "DeprecatedLookupContext.h" | ||||
| #include "LookupContext.h" | ||||
| #include "CppDocument.h" | ||||
| #include "CppBindings.h" | ||||
| #include "Semantic.h" | ||||
| @@ -73,6 +73,7 @@ protected: | ||||
|     using ASTVisitor::endVisit; | ||||
|  | ||||
|     QString matchingLine(const Token &tk) const; | ||||
|     Scope *scopeAt(unsigned tokenIndex) const; | ||||
|  | ||||
|     void reportResult(unsigned tokenIndex, const QList<Symbol *> &candidates); | ||||
|     void reportResult(unsigned tokenIndex); | ||||
| @@ -82,8 +83,6 @@ protected: | ||||
|     bool checkScope(Symbol *symbol, Symbol *otherSymbol) const; | ||||
|     void checkExpression(unsigned startToken, unsigned endToken); | ||||
|  | ||||
|     DeprecatedLookupContext currentContext(AST *ast); | ||||
|  | ||||
|     void ensureNameIsValid(NameAST *ast); | ||||
|  | ||||
|     virtual bool visit(MemInitializerAST *ast); | ||||
| @@ -108,6 +107,7 @@ private: | ||||
|     Symbol *_declSymbol; | ||||
|     Document::Ptr _doc; | ||||
|     Snapshot _snapshot; | ||||
|     LookupContext _context; | ||||
|     QByteArray _source; | ||||
|     Document::Ptr _exprDoc; | ||||
|     Semantic _sem; | ||||
| @@ -116,7 +116,6 @@ private: | ||||
|     QList<QualifiedNameAST *> _qualifiedNameStack; | ||||
|     QList<int> _references; | ||||
|     QList<Usage> _usages; | ||||
|     DeprecatedLookupContext _previousContext; | ||||
|     int _inSimpleDeclaration; | ||||
|     bool _inQProperty; | ||||
|     QSet<unsigned> _processed; | ||||
|   | ||||
| @@ -185,16 +185,6 @@ ClassOrNamespace *LookupContext::classOrNamespace(const Name *name, Symbol *last | ||||
|     return classOrNamespace(name, scope); | ||||
| } | ||||
|  | ||||
| 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; | ||||
|   | ||||
| @@ -214,12 +214,10 @@ 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; | ||||
|  | ||||
|     ClassOrNamespace *classOrNamespace(const Name *name, Symbol *lastVisibleSymbol) const; | ||||
|     ClassOrNamespace *classOrNamespace(const Name *name, Scope *scope) const; | ||||
|     ClassOrNamespace *classOrNamespace(Symbol *symbol) const; | ||||
|  | ||||
| @@ -233,6 +231,8 @@ public: | ||||
|  | ||||
|     static QList<const Name *> fullyQualifiedName(Symbol *symbol); | ||||
|  | ||||
|     Q_DECL_DEPRECATED ClassOrNamespace *classOrNamespace(const Name *name, Symbol *lastVisibleSymbol) const; | ||||
|  | ||||
| private: | ||||
|     Control *_control; | ||||
|  | ||||
|   | ||||
| @@ -39,16 +39,12 @@ using namespace CPlusPlus; | ||||
| uint CPlusPlus::qHash(const CPlusPlus::LookupItem &key) | ||||
| { | ||||
|     const uint h1 = QT_PREPEND_NAMESPACE(qHash)(key.type().type()); | ||||
|     const uint h2 = QT_PREPEND_NAMESPACE(qHash)(key.lastVisibleSymbol()); | ||||
|     const uint h2 = QT_PREPEND_NAMESPACE(qHash)(key.scope()); | ||||
|     return ((h1 << 16) | (h1 >> 16)) ^ h2; | ||||
| } | ||||
|  | ||||
| LookupItem::LookupItem() | ||||
|     : _lastVisibleSymbol(0), _declaration(0) | ||||
| { } | ||||
|  | ||||
| LookupItem::LookupItem(const FullySpecifiedType &type, Symbol *lastVisibleSymbol, Symbol *declaration) | ||||
|     : _type(type), _lastVisibleSymbol(lastVisibleSymbol), _declaration(declaration) | ||||
|     : _scope(0), _declaration(0) | ||||
| { } | ||||
|  | ||||
| FullySpecifiedType LookupItem::type() const | ||||
| @@ -63,15 +59,20 @@ Symbol *LookupItem::declaration() const | ||||
| void LookupItem::setDeclaration(Symbol *declaration) | ||||
| { _declaration = declaration; } | ||||
|  | ||||
| Symbol *LookupItem::lastVisibleSymbol() const | ||||
| { return _lastVisibleSymbol; } | ||||
| Scope *LookupItem::scope() const | ||||
| { | ||||
|     if (! _scope && _declaration) | ||||
|         return _declaration->scope(); | ||||
|  | ||||
| void LookupItem::setLastVisibleSymbol(Symbol *symbol) | ||||
| { _lastVisibleSymbol = symbol; } | ||||
|     return _scope; | ||||
| } | ||||
|  | ||||
| void LookupItem::setScope(Scope *scope) | ||||
| { _scope = scope; } | ||||
|  | ||||
| bool LookupItem::operator == (const LookupItem &other) const | ||||
| { | ||||
|     if (_type == other._type && _declaration == other._declaration && _lastVisibleSymbol == other._lastVisibleSymbol) | ||||
|     if (_type == other._type && _declaration == other._declaration && _scope == other._scope) | ||||
|         return true; | ||||
|  | ||||
|     return false; | ||||
|   | ||||
| @@ -41,9 +41,6 @@ public: | ||||
|     /// Constructs an null LookupItem. | ||||
|     LookupItem(); | ||||
|  | ||||
|     /// Contructs a LookupItem with the given \a type, \a lastVisibleSymbol and \a declaration. | ||||
|     LookupItem(const FullySpecifiedType &type, Symbol *lastVisibleSymbol, Symbol *declaration = 0); | ||||
|  | ||||
|     /// Returns this item's type. | ||||
|     FullySpecifiedType type() const; | ||||
|  | ||||
| @@ -51,23 +48,23 @@ public: | ||||
|     void setType(const FullySpecifiedType &type); | ||||
|  | ||||
|     /// Returns the last visible symbol. | ||||
|     Symbol *lastVisibleSymbol() const; | ||||
|  | ||||
|     /// Sets the last visible symbol. | ||||
|     void setLastVisibleSymbol(Symbol *symbol); | ||||
|  | ||||
|     /// Returns this item's declaration. | ||||
|     Symbol *declaration() const; | ||||
|  | ||||
|     /// Sets this item's declaration. | ||||
|     /// Sets the last visible symbol. | ||||
|     void setDeclaration(Symbol *declaration); | ||||
|  | ||||
|     /// Returns this item's scope. | ||||
|     Scope *scope() const; | ||||
|  | ||||
|     /// Sets this item's scope. | ||||
|     void setScope(Scope *scope); | ||||
|  | ||||
|     bool operator == (const LookupItem &other) const; | ||||
|     bool operator != (const LookupItem &other) const; | ||||
|  | ||||
| private: | ||||
|     FullySpecifiedType _type; | ||||
|     Symbol *_lastVisibleSymbol; | ||||
|     Scope *_scope; | ||||
|     Symbol *_declaration; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -70,21 +70,9 @@ static QList<_Tp> removeDuplicates(const QList<_Tp> &results) | ||||
| ///////////////////////////////////////////////////////////////////// | ||||
| // ResolveExpression | ||||
| ///////////////////////////////////////////////////////////////////// | ||||
| ResolveExpression::ResolveExpression(Symbol *lastVisibleSymbol, const LookupContext &context) | ||||
| ResolveExpression::ResolveExpression(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), | ||||
|       _scope(0), | ||||
|       _context(context), | ||||
|       sem(context.expressionDocument()->translationUnit()) | ||||
| { } | ||||
| @@ -92,15 +80,28 @@ ResolveExpression::ResolveExpression(Scope *scope, const LookupContext &context) | ||||
| ResolveExpression::~ResolveExpression() | ||||
| { } | ||||
|  | ||||
| QList<LookupItem> ResolveExpression::operator()(ExpressionAST *ast) | ||||
| QList<LookupItem> ResolveExpression::operator()(ExpressionAST *ast, Scope *scope) | ||||
| { return resolve(ast, scope); } | ||||
|  | ||||
| QList<LookupItem> ResolveExpression::resolve(ExpressionAST *ast, Scope *scope) | ||||
| { | ||||
|     Q_ASSERT(scope != 0); | ||||
|  | ||||
|     Scope *previousVisibleSymbol = _scope; | ||||
|     _scope = scope; | ||||
|     const QList<LookupItem> result = resolve(ast); | ||||
|     _scope = previousVisibleSymbol; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| QList<LookupItem> ResolveExpression::resolve(ExpressionAST *ast) | ||||
| { | ||||
|     const QList<LookupItem> previousResults = switchResults(QList<LookupItem>()); | ||||
|     accept(ast); | ||||
|     return removeDuplicates(switchResults(previousResults)); | ||||
| } | ||||
|  | ||||
| QList<LookupItem> | ||||
| ResolveExpression::switchResults(const QList<LookupItem> &results) | ||||
| QList<LookupItem> ResolveExpression::switchResults(const QList<LookupItem> &results) | ||||
| { | ||||
|     const QList<LookupItem> previousResults = _results; | ||||
|     _results = results; | ||||
| @@ -109,23 +110,25 @@ ResolveExpression::switchResults(const QList<LookupItem> &results) | ||||
|  | ||||
| void ResolveExpression::addResults(const QList<Symbol *> &symbols) | ||||
| { | ||||
|     foreach (Symbol *s, symbols) { | ||||
|         LookupItem item(s->type(), s, s); | ||||
|     foreach (Symbol *symbol, symbols) { | ||||
|         LookupItem item; | ||||
|         item.setType(symbol->type()); | ||||
|         item.setScope(symbol->scope()); | ||||
|         item.setDeclaration(symbol); | ||||
|         _results.append(item); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void ResolveExpression::addResult(const FullySpecifiedType &ty, Symbol *symbol) | ||||
| void ResolveExpression::addResult(const FullySpecifiedType &ty, Scope *scope) | ||||
| { | ||||
|     if (! symbol) { | ||||
|         if (_scope) | ||||
|             symbol = _scope->owner(); | ||||
|     Q_ASSERT(scope != 0); | ||||
| #warning fix the signature of addResult. | ||||
|  | ||||
|         else | ||||
|             symbol = _context.thisDocument()->globalNamespace(); | ||||
|     } | ||||
|     LookupItem item; | ||||
|     item.setType(ty); | ||||
|     item.setScope(scope); | ||||
|  | ||||
|     _results.append(LookupItem(ty, symbol)); | ||||
|     _results.append(item); | ||||
| } | ||||
|  | ||||
| bool ResolveExpression::visit(BinaryExpressionAST *ast) | ||||
| @@ -155,7 +158,9 @@ bool ResolveExpression::visit(BinaryExpressionAST *ast) | ||||
|  | ||||
| bool ResolveExpression::visit(CastExpressionAST *ast) | ||||
| { | ||||
|     addResult(sem.check(ast->type_id, _context.expressionDocument()->globalSymbols())); | ||||
|     Scope *dummyScope = _context.expressionDocument()->globalSymbols(); | ||||
|     FullySpecifiedType ty = sem.check(ast->type_id, dummyScope); | ||||
|     addResult(ty, _scope); | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| @@ -178,14 +183,16 @@ bool ResolveExpression::visit(ConditionalExpressionAST *ast) | ||||
|  | ||||
| bool ResolveExpression::visit(CppCastExpressionAST *ast) | ||||
| { | ||||
|     addResult(sem.check(ast->type_id, _context.expressionDocument()->globalSymbols())); | ||||
|     Scope *dummyScope = _context.expressionDocument()->globalSymbols(); | ||||
|     FullySpecifiedType ty = sem.check(ast->type_id, dummyScope); | ||||
|     addResult(ty, _scope); | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| bool ResolveExpression::visit(DeleteExpressionAST *) | ||||
| { | ||||
|     FullySpecifiedType ty(control()->voidType()); | ||||
|     addResult(ty); | ||||
|     addResult(ty, _scope); | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| @@ -198,11 +205,11 @@ bool ResolveExpression::visit(ArrayInitializerAST *) | ||||
| bool ResolveExpression::visit(NewExpressionAST *ast) | ||||
| { | ||||
|     if (ast->new_type_id) { | ||||
|         Scope *scope = _context.expressionDocument()->globalSymbols(); | ||||
|         FullySpecifiedType ty = sem.check(ast->new_type_id->type_specifier_list, scope); | ||||
|         ty = sem.check(ast->new_type_id->ptr_operator_list, ty, scope); | ||||
|         Scope *dummyScope = _context.expressionDocument()->globalSymbols(); | ||||
|         FullySpecifiedType ty = sem.check(ast->new_type_id->type_specifier_list, dummyScope); | ||||
|         ty = sem.check(ast->new_type_id->ptr_operator_list, ty, dummyScope); | ||||
|         FullySpecifiedType ptrTy(control()->pointerType(ty)); | ||||
|         addResult(ptrTy); | ||||
|         addResult(ptrTy, _scope); | ||||
|     } | ||||
|     // nothing to do. | ||||
|     return false; | ||||
| @@ -216,7 +223,7 @@ bool ResolveExpression::visit(TypeidExpressionAST *) | ||||
|  | ||||
|     const Name *q = control()->qualifiedNameId(std_type_info, 2, /*global=*/ true); | ||||
|     FullySpecifiedType ty(control()->namedType(q)); | ||||
|     addResult(ty); | ||||
|     addResult(ty, _scope); | ||||
|  | ||||
|     return false; | ||||
| } | ||||
| @@ -248,7 +255,7 @@ bool ResolveExpression::visit(SizeofExpressionAST *) | ||||
| { | ||||
|     FullySpecifiedType ty(control()->integerType(IntegerType::Int)); | ||||
|     ty.setUnsigned(true); | ||||
|     addResult(ty); | ||||
|     addResult(ty, _scope); | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| @@ -280,14 +287,14 @@ bool ResolveExpression::visit(NumericLiteralAST *ast) | ||||
|     if (literal->isUnsigned()) | ||||
|         ty.setUnsigned(true); | ||||
|  | ||||
|     addResult(ty); | ||||
|     addResult(ty, _scope); | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| bool ResolveExpression::visit(BoolLiteralAST *) | ||||
| { | ||||
|     FullySpecifiedType ty(control()->integerType(IntegerType::Bool)); | ||||
|     addResult(ty); | ||||
|     addResult(ty, _scope); | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| @@ -307,7 +314,7 @@ void ResolveExpression::thisObject() | ||||
|                 Class *klass = cscope->owner()->asClass(); | ||||
|                 FullySpecifiedType classTy(control()->namedType(klass->name())); | ||||
|                 FullySpecifiedType ptrTy(control()->pointerType(classTy)); | ||||
|                 addResult(ptrTy, fun); | ||||
|                 addResult(ptrTy, fun->scope()); | ||||
|                 break; | ||||
|             } else if (const QualifiedNameId *q = fun->name()->asQualifiedNameId()) { | ||||
|                 const Name *nestedNameSpecifier = 0; | ||||
| @@ -317,7 +324,7 @@ void ResolveExpression::thisObject() | ||||
|                     nestedNameSpecifier = control()->qualifiedNameId(q->names(), q->nameCount() - 1); | ||||
|                 FullySpecifiedType classTy(control()->namedType(nestedNameSpecifier)); | ||||
|                 FullySpecifiedType ptrTy(control()->pointerType(classTy)); | ||||
|                 addResult(ptrTy, fun); | ||||
|                 addResult(ptrTy, fun->scope()); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
| @@ -344,7 +351,7 @@ bool ResolveExpression::visit(StringLiteralAST *) | ||||
|     FullySpecifiedType charTy = control()->integerType(IntegerType::Char); | ||||
|     charTy.setConst(true); | ||||
|     FullySpecifiedType ty(control()->pointerType(charTy)); | ||||
|     addResult(ty); | ||||
|     addResult(ty, _scope); | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| @@ -419,7 +426,7 @@ bool ResolveExpression::visit(TemplateIdAST *ast) | ||||
| bool ResolveExpression::visit(DestructorNameAST *) | ||||
| { | ||||
|     FullySpecifiedType ty(control()->voidType()); | ||||
|     addResult(ty); | ||||
|     addResult(ty, _scope); | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| @@ -466,7 +473,7 @@ bool ResolveExpression::visit(CallAST *ast) | ||||
|  | ||||
|     //QList< QList<Result> > arguments; | ||||
|     for (ExpressionListAST *exprIt = ast->expression_list; exprIt; exprIt = exprIt->next) { | ||||
|         //arguments.append(operator()(exprIt->expression)); | ||||
|         //arguments.append(resolve(exprIt->expression)); | ||||
|         ++actualArgumentCount; | ||||
|     } | ||||
|  | ||||
| @@ -474,15 +481,15 @@ bool ResolveExpression::visit(CallAST *ast) | ||||
|  | ||||
|     foreach (const LookupItem &result, baseResults) { | ||||
|         FullySpecifiedType ty = result.type().simplified(); | ||||
|         Symbol *lastVisibleSymbol = result.lastVisibleSymbol(); | ||||
|         Scope *scope = result.scope(); | ||||
|  | ||||
|         if (NamedType *namedTy = ty->asNamedType()) { | ||||
|             if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), lastVisibleSymbol)) { | ||||
|             if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), scope)) { | ||||
|                 foreach (Symbol *overload, b->find(functionCallOp)) { | ||||
|                     if (Function *funTy = overload->type()->asFunctionType()) { | ||||
|                         if (maybeValidPrototype(funTy, actualArgumentCount)) { | ||||
|                             Function *proto = instantiate(namedTy->name(), funTy)->asFunctionType(); | ||||
|                             addResult(proto->returnType().simplified(), lastVisibleSymbol); | ||||
|                             addResult(proto->returnType().simplified(), scope); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| @@ -490,12 +497,12 @@ bool ResolveExpression::visit(CallAST *ast) | ||||
|  | ||||
|         } else if (Function *funTy = ty->asFunctionType()) { | ||||
|             if (maybeValidPrototype(funTy, actualArgumentCount)) | ||||
|                 addResult(funTy->returnType().simplified(), lastVisibleSymbol); | ||||
|                 addResult(funTy->returnType().simplified(), scope); | ||||
|  | ||||
|         } else if (Class *classTy = ty->asClassType()) { | ||||
|             // Constructor call | ||||
|             FullySpecifiedType ctorTy = control()->namedType(classTy->name()); | ||||
|             addResult(ctorTy, lastVisibleSymbol); | ||||
|             addResult(ctorTy, scope); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -507,27 +514,27 @@ bool ResolveExpression::visit(ArrayAccessAST *ast) | ||||
|     const QList<LookupItem> baseResults = _results; | ||||
|     _results.clear(); | ||||
|  | ||||
|     const QList<LookupItem> indexResults = operator()(ast->expression); | ||||
|     const QList<LookupItem> indexResults = resolve(ast->expression); | ||||
|  | ||||
|     const Name *arrayAccessOp = control()->operatorNameId(OperatorNameId::ArrayAccessOp); | ||||
|  | ||||
|     foreach (const LookupItem &result, baseResults) { | ||||
|         FullySpecifiedType ty = result.type().simplified(); | ||||
|         Symbol *lastVisibleSymbol = result.lastVisibleSymbol(); | ||||
|         Scope *scope = result.scope(); | ||||
|  | ||||
|         if (PointerType *ptrTy = ty->asPointerType()) { | ||||
|             addResult(ptrTy->elementType().simplified(), lastVisibleSymbol); | ||||
|             addResult(ptrTy->elementType().simplified(), scope); | ||||
|  | ||||
|         } else if (ArrayType *arrTy = ty->asArrayType()) { | ||||
|             addResult(arrTy->elementType().simplified(), lastVisibleSymbol); | ||||
|             addResult(arrTy->elementType().simplified(), scope); | ||||
|  | ||||
|         } else if (NamedType *namedTy = ty->asNamedType()) { | ||||
|             if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), lastVisibleSymbol)) { | ||||
|             if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), scope)) { | ||||
|                 foreach (Symbol *overload, b->find(arrayAccessOp)) { | ||||
|                     if (Function *funTy = overload->type()->asFunctionType()) { | ||||
|                         Function *proto = instantiate(namedTy->name(), funTy)->asFunctionType(); | ||||
|                         // ### TODO: check the actual arguments | ||||
|                         addResult(proto->returnType().simplified(), lastVisibleSymbol); | ||||
|                         addResult(proto->returnType().simplified(), scope); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
| @@ -567,7 +574,7 @@ ResolveExpression::resolveBaseExpression(const QList<LookupItem> &baseResults, i | ||||
|  | ||||
|     LookupItem result = baseResults.first(); | ||||
|     FullySpecifiedType ty = result.type().simplified(); | ||||
|     Symbol *lastVisibleSymbol = result.lastVisibleSymbol(); | ||||
|     Scope *scope = result.scope(); | ||||
|  | ||||
|     if (Function *funTy = ty->asFunctionType()) { | ||||
|         if (funTy->isAmbiguous()) | ||||
| @@ -578,26 +585,36 @@ ResolveExpression::resolveBaseExpression(const QList<LookupItem> &baseResults, i | ||||
|         if (NamedType *namedTy = ty->asNamedType()) { | ||||
|             const Name *arrowAccessOp = control()->operatorNameId(OperatorNameId::ArrowOp); | ||||
|  | ||||
|             foreach (Symbol *s, _context.lookup(namedTy->name(), result.lastVisibleSymbol())) { | ||||
|                 if (PointerType *ptrTy = s->type()->asPointerType()) { | ||||
|             foreach (Symbol *declaration, _context.lookup(namedTy->name(), result.scope())) { | ||||
|                 if (PointerType *ptrTy = declaration->type()->asPointerType()) { | ||||
|                     FullySpecifiedType elementTy = ptrTy->elementType().simplified(); | ||||
|  | ||||
|                     if (elementTy->isNamedType() || elementTy->isClassType()) | ||||
|                         results.append(LookupItem(elementTy, lastVisibleSymbol)); | ||||
|                     if (elementTy->isNamedType() || elementTy->isClassType()) { | ||||
|                         LookupItem item; | ||||
|                         item.setType(elementTy); | ||||
|                         item.setDeclaration(declaration); | ||||
|                         results.append(item); | ||||
|                     } | ||||
|  | ||||
|                 } else if (const NamedType *nt = s->type()->asNamedType()) { | ||||
|                     Symbol *l = _context.lookup(nt->name(), result.lastVisibleSymbol()).first(); | ||||
|                 } else if (const NamedType *nt = declaration->type()->asNamedType()) { | ||||
| #warning fix this code | ||||
|                     qWarning() << Q_FUNC_INFO << __LINE__; | ||||
|                     Symbol *declaration = _context.lookup(nt->name(), result.scope()).first(); | ||||
|  | ||||
|                     if (PointerType *ptrTy = l->type()->asPointerType()) { | ||||
|                     if (PointerType *ptrTy = declaration->type()->asPointerType()) { | ||||
|                         FullySpecifiedType elementTy = ptrTy->elementType().simplified(); | ||||
|  | ||||
|                         if (elementTy->isNamedType() || elementTy->isClassType()) | ||||
|                             results.append(LookupItem(elementTy, lastVisibleSymbol)); | ||||
|                         if (elementTy->isNamedType() || elementTy->isClassType()) { | ||||
|                             LookupItem item; | ||||
|                             item.setType(elementTy); | ||||
|                             item.setDeclaration(declaration); | ||||
|                             results.append(item); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), result.lastVisibleSymbol())) { | ||||
|             if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), result.scope())) { | ||||
|                 foreach (Symbol *overload, b->find(arrowAccessOp)) { | ||||
|                     if (Function *funTy = overload->type()->asFunctionType()) { | ||||
|                         FullySpecifiedType f = instantiate(namedTy->name(), funTy); | ||||
| @@ -605,7 +622,11 @@ ResolveExpression::resolveBaseExpression(const QList<LookupItem> &baseResults, i | ||||
|  | ||||
|                         if (PointerType *ptrTy = retTy->asPointerType()) { | ||||
|                             FullySpecifiedType elementTy = ptrTy->elementType().simplified(); | ||||
|                             results.append(LookupItem(elementTy, overload)); | ||||
|  | ||||
|                             LookupItem item; | ||||
|                             item.setType(elementTy); | ||||
|                             item.setDeclaration(overload); | ||||
|                             results.append(item); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| @@ -614,8 +635,12 @@ ResolveExpression::resolveBaseExpression(const QList<LookupItem> &baseResults, i | ||||
|         } else if (PointerType *ptrTy = ty->asPointerType()) { | ||||
|             FullySpecifiedType elementTy = ptrTy->elementType().simplified(); | ||||
|  | ||||
|             if (elementTy->isNamedType() || elementTy->isClassType()) | ||||
|                 results.append(LookupItem(elementTy, lastVisibleSymbol)); | ||||
|             if (elementTy->isNamedType() || elementTy->isClassType()) { | ||||
|                 LookupItem item; | ||||
|                 item.setType(elementTy); | ||||
|                 item.setScope(scope); | ||||
|                 results.append(item); | ||||
|             } | ||||
|         } | ||||
|     } else if (accessOp == T_DOT) { | ||||
|         if (replacedDotOperator) { | ||||
| @@ -629,27 +654,24 @@ ResolveExpression::resolveBaseExpression(const QList<LookupItem> &baseResults, i | ||||
|         } | ||||
|  | ||||
|         if (NamedType *namedTy = ty->asNamedType()) { | ||||
|             const QList<Symbol *> candidates = _context.lookup(namedTy->name(), result.lastVisibleSymbol()); | ||||
|             foreach (Symbol *candidate, candidates) { | ||||
|                 if (candidate->isTypedef() && candidate->type()->isNamedType()) { | ||||
|                     ty = candidate->type(); | ||||
|                     lastVisibleSymbol = candidate; | ||||
|                     break; | ||||
|                 } else if (TypenameArgument *arg = candidate->asTypenameArgument()) { | ||||
|                     ty = arg->type(); | ||||
|                     lastVisibleSymbol = candidate; | ||||
|                     break; | ||||
|             if (ClassOrNamespace *binding = _context.classOrNamespace(namedTy->name(), result.scope())) { | ||||
|                 foreach (Symbol *s, binding->symbols()) { | ||||
|                     LookupItem item; | ||||
|                     item.setType(s->type()); | ||||
|                     item.setDeclaration(s); | ||||
|                     results.append(item); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             results.append(LookupItem(ty, lastVisibleSymbol)); | ||||
|  | ||||
|         } else if (Function *fun = ty->asFunctionType()) { | ||||
|             Scope *funScope = fun->scope(); | ||||
|  | ||||
|             if (funScope && (funScope->isBlockScope() || funScope->isNamespaceScope())) { | ||||
|                 FullySpecifiedType retTy = fun->returnType().simplified(); | ||||
|                 results.append(LookupItem(retTy, lastVisibleSymbol)); | ||||
|                 LookupItem item; | ||||
|                 item.setType(retTy); | ||||
|                 item.setDeclaration(fun); | ||||
|                 results.append(item); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -674,9 +696,13 @@ ResolveExpression::resolveMemberExpression(const QList<LookupItem> &baseResults, | ||||
|             results += resolveMember(memberName, klass); | ||||
|  | ||||
|         else if (NamedType *namedTy = ty->asNamedType()) { | ||||
|             if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), r.lastVisibleSymbol())) { | ||||
|                 foreach (Symbol *c, b->find(memberName)) | ||||
|                     results.append(LookupItem(instantiate(namedTy->name(), c), c)); | ||||
|             if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), r.scope())) { | ||||
|                 foreach (Symbol *overload, b->find(memberName)) { | ||||
|                     LookupItem item; | ||||
|                     item.setType(instantiate(namedTy->name(), overload)); | ||||
|                     item.setDeclaration(overload); | ||||
|                     results.append(item); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -689,9 +715,8 @@ FullySpecifiedType ResolveExpression::instantiate(const Name *className, Symbol | ||||
|     return GenTemplateInstance::instantiate(className, candidate, _context.control()); | ||||
| } | ||||
|  | ||||
| QList<LookupItem> | ||||
| ResolveExpression::resolveMember(const Name *memberName, Class *klass, | ||||
|                                  const Name *className) const | ||||
| QList<LookupItem> ResolveExpression::resolveMember(const Name *memberName, Class *klass, | ||||
|                                                    const Name *className) const | ||||
| { | ||||
|     QList<LookupItem> results; | ||||
|  | ||||
| @@ -716,15 +741,17 @@ ResolveExpression::resolveMember(const Name *memberName, Class *klass, | ||||
|         if (const TemplateNameId *templId = unqualifiedNameId->asTemplateNameId()) | ||||
|             ty = GenTemplateInstance::instantiate(templId, candidate, _context.control()); | ||||
|  | ||||
|         results.append(LookupItem(ty, candidate)); | ||||
|         LookupItem item; | ||||
|         item.setType(ty); | ||||
|         item.setDeclaration(candidate); | ||||
|         results.append(item); | ||||
|     } | ||||
|  | ||||
|     return removeDuplicates(results); | ||||
| } | ||||
|  | ||||
|  | ||||
| QList<LookupItem> | ||||
| ResolveExpression::resolveMember(const Name *memberName, ObjCClass *klass) const | ||||
| QList<LookupItem> ResolveExpression::resolveMember(const Name *memberName, ObjCClass *klass) const | ||||
| { | ||||
|     QList<LookupItem> results; | ||||
|     if (!memberName || !klass) | ||||
| @@ -734,8 +761,10 @@ ResolveExpression::resolveMember(const Name *memberName, ObjCClass *klass) const | ||||
|  | ||||
|     foreach (Symbol *candidate, candidates) { | ||||
|         FullySpecifiedType ty = candidate->type(); | ||||
|  | ||||
|         results.append(LookupItem(ty, candidate)); | ||||
|         LookupItem item; | ||||
|         item.setType(ty); | ||||
|         item.setDeclaration(candidate); | ||||
|         results.append(item); | ||||
|     } | ||||
|  | ||||
|     return removeDuplicates(results); | ||||
| @@ -748,7 +777,7 @@ bool ResolveExpression::visit(PostIncrDecrAST *) | ||||
|  | ||||
| bool ResolveExpression::visit(ObjCMessageExpressionAST *ast) | ||||
| { | ||||
|     QList<LookupItem> receiverResults = operator()(ast->receiver_expression); | ||||
|     const QList<LookupItem> receiverResults = resolve(ast->receiver_expression); | ||||
|  | ||||
|     if (!receiverResults.isEmpty()) { | ||||
|         LookupItem result = receiverResults.first(); | ||||
| @@ -769,7 +798,7 @@ bool ResolveExpression::visit(ObjCMessageExpressionAST *ast) | ||||
|         } | ||||
|  | ||||
|         if (klassName&&ast->selector && ast->selector->name) { | ||||
|             const QList<Symbol *> resolvedSymbols = _context.lookup(klassName, result.lastVisibleSymbol()); | ||||
|             const QList<Symbol *> resolvedSymbols = _context.lookup(klassName, result.scope()); | ||||
|             foreach (Symbol *resolvedSymbol, resolvedSymbols) | ||||
|                 if (ObjCClass *klass = resolvedSymbol->asObjCClass()) | ||||
|                     _results.append(resolveMember(ast->selector->name, klass)); | ||||
|   | ||||
| @@ -41,12 +41,11 @@ namespace CPlusPlus { | ||||
| class CPLUSPLUS_EXPORT ResolveExpression: protected ASTVisitor | ||||
| { | ||||
| public: | ||||
|     ResolveExpression(Symbol *lastVisibleSymbol, const LookupContext &context); | ||||
|     ResolveExpression(Scope *scope, const LookupContext &context); | ||||
|  | ||||
|     ResolveExpression(const LookupContext &context); | ||||
|     virtual ~ResolveExpression(); | ||||
|  | ||||
|     QList<LookupItem> operator()(ExpressionAST *ast); | ||||
|     QList<LookupItem> operator()(ExpressionAST *ast, Scope *scope); | ||||
|     QList<LookupItem> resolve(ExpressionAST *ast, Scope *scope); | ||||
|  | ||||
|     QList<LookupItem> resolveMemberExpression(const QList<LookupItem> &baseResults, | ||||
|                                               unsigned accessOp, | ||||
| @@ -57,19 +56,20 @@ public: | ||||
|                                             int accessOp, | ||||
|                                             bool *replacedDotOperator = 0) const; | ||||
|  | ||||
| protected: | ||||
|     QList<LookupItem> resolve(ExpressionAST *ast); | ||||
|  | ||||
|     Q_DECL_DEPRECATED QList<LookupItem> resolveMember(const Name *memberName, Class *klass, | ||||
|                                                       const Name *className = 0) 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); | ||||
|  | ||||
|     void addResult(const FullySpecifiedType &ty, Scope *scope); | ||||
|     void addResults(const QList<Symbol *> &symbols); | ||||
|  | ||||
|     bool maybeValidPrototype(Function *funTy, unsigned actualArgumentCount) const; | ||||
| @@ -118,7 +118,6 @@ protected: | ||||
|     virtual bool visit(ObjCMessageExpressionAST *ast); | ||||
|  | ||||
| private: | ||||
|     Symbol *_lastVisibleSymbol; | ||||
|     Scope *_scope; | ||||
|     LookupContext _context; | ||||
|     Semantic sem; | ||||
|   | ||||
| @@ -34,13 +34,14 @@ | ||||
| #include "pp.h" | ||||
|  | ||||
| #include <AST.h> | ||||
| #include <Symbol.h> | ||||
| #include <QSet> | ||||
|  | ||||
| using namespace CPlusPlus; | ||||
|  | ||||
| TypeOfExpression::TypeOfExpression(): | ||||
|     m_ast(0), | ||||
|     m_lastVisibleSymbol(0) | ||||
|     m_scope(0) | ||||
| { | ||||
| } | ||||
|  | ||||
| @@ -49,7 +50,7 @@ void TypeOfExpression::reset() | ||||
|     m_thisDocument.clear(); | ||||
|     m_snapshot = Snapshot(); | ||||
|     m_ast = 0; | ||||
|     m_lastVisibleSymbol = 0; | ||||
|     m_scope = 0; | ||||
|     m_lookupContext = LookupContext(); | ||||
|     m_bindings.clear(); | ||||
|     m_environment.clear(); | ||||
| @@ -61,14 +62,14 @@ void TypeOfExpression::init(Document::Ptr thisDocument, const Snapshot &snapshot | ||||
|     m_thisDocument = thisDocument; | ||||
|     m_snapshot = snapshot; | ||||
|     m_ast = 0; | ||||
|     m_lastVisibleSymbol = 0; | ||||
|     m_scope = 0; | ||||
|     m_lookupContext = LookupContext(); | ||||
|     m_bindings = bindings; | ||||
|     m_environment.clear(); | ||||
| } | ||||
|  | ||||
| QList<LookupItem> TypeOfExpression::operator()(const QString &expression, | ||||
|                                                Symbol *lastVisibleSymbol, | ||||
|                                                Scope *scope, | ||||
|                                                PreprocessMode mode) | ||||
| { | ||||
|     QString code = expression; | ||||
| @@ -80,13 +81,14 @@ QList<LookupItem> TypeOfExpression::operator()(const QString &expression, | ||||
|     expressionDoc->check(); | ||||
|     m_ast = extractExpressionAST(expressionDoc); | ||||
|  | ||||
|     m_lastVisibleSymbol = lastVisibleSymbol; | ||||
|     m_scope = scope; | ||||
|  | ||||
|     m_lookupContext = LookupContext(expressionDoc, m_thisDocument, m_snapshot); | ||||
|     m_lookupContext.setBindings(m_bindings); | ||||
|  | ||||
|     ResolveExpression resolveExpression(lastVisibleSymbol, m_lookupContext); | ||||
|     return resolveExpression(m_ast); | ||||
|     ResolveExpression resolve(m_lookupContext); | ||||
| #warning fix the signature of operator() | ||||
|     return resolve(m_ast, scope); | ||||
| } | ||||
|  | ||||
| QString TypeOfExpression::preprocess(const QString &expression) const | ||||
| @@ -99,9 +101,9 @@ ExpressionAST *TypeOfExpression::ast() const | ||||
|     return m_ast; | ||||
| } | ||||
|  | ||||
| Symbol *TypeOfExpression::lastVisibleSymbol() const | ||||
| Scope *TypeOfExpression::scope() const | ||||
| { | ||||
|     return m_lastVisibleSymbol; | ||||
|     return m_scope; | ||||
| } | ||||
|  | ||||
| const LookupContext &TypeOfExpression::lookupContext() const | ||||
|   | ||||
| @@ -76,10 +76,10 @@ public: | ||||
|      * has been made! | ||||
|      * | ||||
|      * @param expression        The expression to evaluate. | ||||
|      * @param lastVisibleSymbol The last visible symbol in the document. | ||||
|      * @param scope             The scope enclosing the expression. | ||||
|      */ | ||||
|     QList<LookupItem> operator()(const QString &expression, | ||||
|                                  Symbol *lastVisibleSymbol, | ||||
|                                  Scope *scope, | ||||
|                                  PreprocessMode mode = NoPreprocess); | ||||
|  | ||||
|     QString preprocess(const QString &expression) const; | ||||
| @@ -93,7 +93,7 @@ public: | ||||
|      * Returns the lookup context of the last evaluated expression. | ||||
|      */ | ||||
|     const LookupContext &lookupContext() const; | ||||
|     Symbol *lastVisibleSymbol() const; | ||||
|     Scope *scope() const; | ||||
|  | ||||
|     ExpressionAST *expressionAST() const; | ||||
|  | ||||
| @@ -111,7 +111,7 @@ private: | ||||
|     Snapshot m_snapshot; | ||||
|     QSharedPointer<CreateBindings> m_bindings; | ||||
|     ExpressionAST *m_ast; | ||||
|     Symbol *m_lastVisibleSymbol; | ||||
|     Scope *m_scope; | ||||
|     LookupContext m_lookupContext; | ||||
|     mutable QSharedPointer<Environment> m_environment; | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user