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;
|
||||
};
|
||||
|
||||
@@ -871,9 +871,7 @@ CPlusPlus::Symbol *CPPEditor::findCanonicalSymbol(const QTextCursor &cursor,
|
||||
TypeOfExpression typeOfExpression;
|
||||
typeOfExpression.init(doc, snapshot);
|
||||
|
||||
Symbol *lastVisibleSymbol = doc->findSymbolAt(line, col);
|
||||
|
||||
const QList<LookupItem> results = typeOfExpression(code, lastVisibleSymbol,
|
||||
const QList<LookupItem> results = typeOfExpression(code, doc->scopeAt(line, col),
|
||||
TypeOfExpression::Preprocess);
|
||||
|
||||
NamespaceBindingPtr glo = bind(doc, snapshot);
|
||||
@@ -1235,6 +1233,10 @@ void CPPEditor::switchDeclarationDefinition()
|
||||
if (!m_modelManager)
|
||||
return;
|
||||
|
||||
#warning implement CPPEditor::switchDeclarationDefinition
|
||||
qWarning() << Q_FUNC_INFO << __LINE__;
|
||||
|
||||
#if 0
|
||||
const Snapshot snapshot = m_modelManager->snapshot();
|
||||
|
||||
Document::Ptr doc = snapshot.document(file()->fileName());
|
||||
@@ -1274,6 +1276,7 @@ void CPPEditor::switchDeclarationDefinition()
|
||||
if (Symbol *def = findDefinition(lastSymbol, snapshot))
|
||||
openCppEditorAt(linkToSymbol(def));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline LookupItem skipForwardDeclarations(const QList<LookupItem> &resolvedSymbols)
|
||||
@@ -1425,8 +1428,8 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
|
||||
}
|
||||
|
||||
// Find the last symbol up to the cursor position
|
||||
Symbol *lastSymbol = doc->findSymbolAt(line, column);
|
||||
if (!lastSymbol)
|
||||
Scope *scope = doc->scopeAt(line, column);
|
||||
if (!scope)
|
||||
return link;
|
||||
|
||||
// Evaluate the type of the expression under the cursor
|
||||
@@ -1435,16 +1438,20 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
|
||||
|
||||
TypeOfExpression typeOfExpression;
|
||||
typeOfExpression.init(doc, snapshot);
|
||||
QList<LookupItem> resolvedSymbols =
|
||||
typeOfExpression(expression, lastSymbol);
|
||||
QList<LookupItem> resolvedSymbols = typeOfExpression(expression, scope, TypeOfExpression::Preprocess);
|
||||
|
||||
if (!resolvedSymbols.isEmpty()) {
|
||||
LookupItem result = skipForwardDeclarations(resolvedSymbols);
|
||||
const LookupItem result = skipForwardDeclarations(resolvedSymbols);
|
||||
|
||||
if (Symbol *symbol = result.lastVisibleSymbol()) {
|
||||
if (Symbol *symbol = result.declaration()) {
|
||||
Symbol *def = 0;
|
||||
|
||||
qWarning() << "find definition?";
|
||||
#warning port me
|
||||
#if 0
|
||||
if (resolveTarget && !lastSymbol->isFunction())
|
||||
def = findDefinition(symbol, snapshot);
|
||||
#endif
|
||||
|
||||
link = linkToSymbol(def ? def : symbol);
|
||||
link.begin = beginOfToken;
|
||||
|
||||
@@ -178,6 +178,9 @@ static QString buildHelpId(Symbol *symbol, const Name *name)
|
||||
return qualifiedNames.join(QLatin1String("::"));
|
||||
}
|
||||
|
||||
#warning implement static FullySpecifiedType resolve()
|
||||
|
||||
#if 0
|
||||
// ### move me
|
||||
static FullySpecifiedType resolve(const FullySpecifiedType &ty,
|
||||
const LookupContext &context,
|
||||
@@ -257,6 +260,7 @@ static FullySpecifiedType resolve(const FullySpecifiedType &ty,
|
||||
|
||||
return ty;
|
||||
}
|
||||
#endif
|
||||
|
||||
void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, int pos)
|
||||
{
|
||||
@@ -270,6 +274,8 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
|
||||
if (!edit)
|
||||
return;
|
||||
|
||||
#warning void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, int pos)
|
||||
#if 0
|
||||
const Snapshot documents = m_modelManager->snapshot();
|
||||
const QString fileName = editor->file()->fileName();
|
||||
Document::Ptr doc = documents.document(fileName);
|
||||
@@ -285,7 +291,7 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
|
||||
// Find the last symbol up to the cursor position
|
||||
int line = 0, column = 0;
|
||||
editor->convertPosition(tc.position(), &line, &column);
|
||||
Symbol *lastSymbol = doc->findSymbolAt(line, column);
|
||||
Scope *scope = doc->scopeAt(line, column);
|
||||
|
||||
TypeOfExpression typeOfExpression;
|
||||
typeOfExpression.init(doc, documents);
|
||||
@@ -336,18 +342,18 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
|
||||
ExpressionUnderCursor expressionUnderCursor;
|
||||
const QString expression = expressionUnderCursor(tc);
|
||||
|
||||
const QList<LookupItem> types = typeOfExpression(expression, lastSymbol);
|
||||
const QList<LookupItem> types = typeOfExpression(expression, scope);
|
||||
|
||||
if (!types.isEmpty()) {
|
||||
const LookupItem result = types.first();
|
||||
|
||||
FullySpecifiedType firstType = result.type(); // result of `type of expression'.
|
||||
Symbol *lookupSymbol = result.lastVisibleSymbol(); // lookup symbol
|
||||
Symbol *lookupSymbol = result.declaration(); // lookup symbol
|
||||
|
||||
Symbol *resolvedSymbol = lookupSymbol;
|
||||
const Name *resolvedName = lookupSymbol ? lookupSymbol->name() : 0;
|
||||
firstType = resolve(firstType, typeOfExpression.lookupContext(),
|
||||
lastSymbol,
|
||||
scope,
|
||||
&resolvedSymbol, &resolvedName);
|
||||
|
||||
if (resolvedSymbol && resolvedSymbol->scope()
|
||||
@@ -362,7 +368,7 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
|
||||
m_helpId = buildHelpId(resolvedSymbol, resolvedName);
|
||||
|
||||
if (m_toolTip.isEmpty()) {
|
||||
Symbol *symbol = result.lastVisibleSymbol();
|
||||
Symbol *symbol = result.declaration();
|
||||
if (resolvedSymbol)
|
||||
symbol = resolvedSymbol;
|
||||
|
||||
@@ -431,4 +437,5 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
|
||||
} else if (!m_toolTip.isEmpty() && Qt::mightBeRichText(m_toolTip)) {
|
||||
m_toolTip = QString(QLatin1String("<nobr>%1")).arg(Qt::escape(m_toolTip));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -754,15 +754,17 @@ int CppCodeCompletion::startCompletionInternal(TextEditor::BaseTextEditor *edit,
|
||||
}
|
||||
}
|
||||
|
||||
Scope *scope = thisDocument->scopeAt(line, column);
|
||||
Q_ASSERT(scope != 0);
|
||||
|
||||
QList<LookupItem> results = typeOfExpression(expression, lastVisibleSymbol, TypeOfExpression::Preprocess);
|
||||
QList<LookupItem> results = typeOfExpression(expression, scope, TypeOfExpression::Preprocess);
|
||||
LookupContext context = typeOfExpression.lookupContext();
|
||||
|
||||
if (results.isEmpty()) {
|
||||
if (m_completionOperator == T_SIGNAL || m_completionOperator == T_SLOT) {
|
||||
if (! (expression.isEmpty() || expression == QLatin1String("this"))) {
|
||||
expression = QLatin1String("this");
|
||||
results = typeOfExpression(expression, lastVisibleSymbol);
|
||||
results = typeOfExpression(expression, scope);
|
||||
}
|
||||
|
||||
if (results.isEmpty())
|
||||
@@ -785,7 +787,7 @@ int CppCodeCompletion::startCompletionInternal(TextEditor::BaseTextEditor *edit,
|
||||
|
||||
// Resolve the type of this expression
|
||||
const QList<LookupItem> results =
|
||||
typeOfExpression(baseExpression, lastVisibleSymbol,
|
||||
typeOfExpression(baseExpression, scope,
|
||||
TypeOfExpression::Preprocess);
|
||||
|
||||
// If it's a class, add completions for the constructors
|
||||
@@ -930,10 +932,10 @@ bool CppCodeCompletion::completeConstructorOrFunction(const QList<LookupItem> &r
|
||||
|
||||
foreach (const LookupItem &result, results) {
|
||||
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->lookup(functionCallOp)) {
|
||||
FullySpecifiedType overloadTy = overload->type().simplified();
|
||||
|
||||
@@ -966,8 +968,8 @@ bool CppCodeCompletion::completeConstructorOrFunction(const QList<LookupItem> &r
|
||||
// find a scope that encloses the current location, starting from the lastVisibileSymbol
|
||||
// and moving outwards
|
||||
Scope *sc = 0;
|
||||
if (typeOfExpression.lastVisibleSymbol())
|
||||
sc = typeOfExpression.lastVisibleSymbol()->scope();
|
||||
if (typeOfExpression.scope())
|
||||
sc = typeOfExpression.scope();
|
||||
else if (context.thisDocument())
|
||||
sc = context.thisDocument()->globalSymbols();
|
||||
|
||||
@@ -1054,7 +1056,7 @@ bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults,
|
||||
if (baseResults.isEmpty())
|
||||
return false;
|
||||
|
||||
ResolveExpression resolveExpression(typeOfExpression.lastVisibleSymbol(), context);
|
||||
ResolveExpression resolveExpression(context);
|
||||
|
||||
bool replacedDotOperator = false;
|
||||
const QList<LookupItem> classObjectResults =
|
||||
@@ -1064,21 +1066,22 @@ bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults,
|
||||
|
||||
ClassOrNamespace *classOrNamespace = 0;
|
||||
|
||||
QList<Symbol *> classObjectCandidates;
|
||||
foreach (const LookupItem &r, classObjectResults) {
|
||||
FullySpecifiedType ty = r.type().simplified();
|
||||
|
||||
if (Class *klass = ty->asClassType())
|
||||
classObjectCandidates.append(klass);
|
||||
|
||||
else if (NamedType *namedTy = ty->asNamedType()) {
|
||||
if (ClassOrNamespace *b = context.classOrNamespace(namedTy->name(), r.lastVisibleSymbol())) {
|
||||
if (Class *klass = ty->asClassType()) {
|
||||
if (ClassOrNamespace *b = context.classOrNamespace(klass)) {
|
||||
classOrNamespace = b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else if (NamedType *namedTy = ty->asNamedType()) {
|
||||
if (ClassOrNamespace *b = context.classOrNamespace(namedTy->name(), r.scope())) {
|
||||
classOrNamespace = b;
|
||||
break;
|
||||
} else {
|
||||
Overview oo;
|
||||
|
||||
qDebug() << "*** no class for" << oo(namedTy->name());
|
||||
}
|
||||
}
|
||||
@@ -1109,10 +1112,10 @@ bool CppCodeCompletion::completeScope(const QList<LookupItem> &results,
|
||||
|
||||
foreach (const LookupItem &result, results) {
|
||||
FullySpecifiedType ty = result.type();
|
||||
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)) {
|
||||
completeClass(b, context);
|
||||
break;
|
||||
}
|
||||
@@ -1353,7 +1356,7 @@ bool CppCodeCompletion::completeQtMethod(const QList<LookupItem> &results,
|
||||
if (results.isEmpty())
|
||||
return false;
|
||||
|
||||
DeprecatedLookupContext context(typeOfExpression.lastVisibleSymbol(),
|
||||
DeprecatedLookupContext context(typeOfExpression.scope()->owner(),
|
||||
newContext.expressionDocument(),
|
||||
newContext.thisDocument(),
|
||||
newContext.snapshot());
|
||||
@@ -1377,7 +1380,7 @@ bool CppCodeCompletion::completeQtMethod(const QList<LookupItem> &results,
|
||||
if (! namedTy) // not a class name.
|
||||
continue;
|
||||
|
||||
ClassOrNamespace *b = newContext.classOrNamespace(namedTy->name(), p.lastVisibleSymbol());
|
||||
ClassOrNamespace *b = newContext.classOrNamespace(namedTy->name(), p.scope());
|
||||
if (! b)
|
||||
continue;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user