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