Commit a2cd5db6 authored by Roberto Raggi's avatar Roberto Raggi
Browse files

Improved the lookup of qualified name ids.

parent 4741a728
......@@ -143,19 +143,59 @@ Identifier *LookupContext::identifier(Name *name) const
return 0;
}
bool LookupContext::maybeValidSymbol(Symbol *symbol,
ResolveMode mode,
const QList<Symbol *> &candidates)
{
if (((mode & ResolveNamespace) && symbol->isNamespace()) ||
((mode & ResolveClass) && symbol->isClass()) ||
(mode & ResolveSymbol)) {
return ! candidates.contains(symbol);
}
return false;
}
QList<Symbol *> LookupContext::resolve(Name *name, const QList<Scope *> &visibleScopes,
ResolveMode mode) const
{
if (QualifiedNameId *q = name->asQualifiedNameId()) {
QList<Symbol *> candidates;
QList<Scope *> scopes = visibleScopes;
Identifier *id = identifier(name);
foreach (Scope *scope, visibleScopes) {
Symbol *symbol = scope->lookat(id);
for (; symbol; symbol = symbol->next()) {
if (! symbol->name())
continue;
else if (! maybeValidSymbol(symbol, mode, candidates))
continue;
QualifiedNameId *qq = symbol->name()->asQualifiedNameId();
if (! qq)
continue;
if (q->nameCount() > qq->nameCount())
continue;
for (int i = q->nameCount() - 1; i != -1; --i) {
Name *a = q->nameAt(i);
Name *b = qq->nameAt(i);
if (! a->isEqualTo(b))
break;
else if (i == 0)
candidates.append(symbol);
}
}
}
for (unsigned i = 0; i < q->nameCount(); ++i) {
Name *name = q->nameAt(i);
QList<Symbol *> candidates;
if (i + 1 == q->nameCount())
candidates = resolve(name, scopes, mode);
candidates += resolve(name, scopes, mode);
else
candidates = resolveClassOrNamespace(name, scopes);
candidates += resolveClassOrNamespace(name, scopes);
if (candidates.isEmpty() || i + 1 == q->nameCount())
return candidates;
......@@ -176,19 +216,41 @@ QList<Symbol *> LookupContext::resolve(Name *name, const QList<Scope *> &visible
for (int scopeIndex = 0; scopeIndex < visibleScopes.size(); ++scopeIndex) {
Scope *scope = visibleScopes.at(scopeIndex);
for (Symbol *symbol = scope->lookat(id); symbol; symbol = symbol->next()) {
if (! symbol->name())
if (! symbol->name()) {
continue;
else if (symbol->name()->isQualifiedNameId())
} else if (! maybeValidSymbol(symbol, mode, candidates)) {
continue;
else if (! isNameCompatibleWithIdentifier(symbol->name(), id))
} else if (QualifiedNameId *q = symbol->name()->asQualifiedNameId()) {
if (! q->unqualifiedNameId()->isEqualTo(name))
continue;
if (q->nameCount() > 1) {
Name *classOrNamespaceName =
control()->qualifiedNameId(q->names(),
q->nameCount() - 1);
const QList<Symbol *> resolvedClassOrNamespace =
resolveClassOrNamespace(classOrNamespaceName, visibleScopes);
bool good = false;
foreach (Symbol *classOrNamespace, resolvedClassOrNamespace) {
ScopedSymbol *scoped = classOrNamespace->asScopedSymbol();
if (visibleScopes.contains(scoped->members())) {
good = true;
break;
}
}
if (! good)
continue;
}
} else if (! isNameCompatibleWithIdentifier(symbol->name(), id)) {
continue;
else if (symbol->name()->isDestructorNameId() != name->isDestructorNameId())
} else if (symbol->name()->isDestructorNameId() != name->isDestructorNameId()) {
continue;
else if ((((mode & ResolveNamespace) && symbol->isNamespace()) ||
((mode & ResolveClass) && symbol->isClass()) ||
(mode & ResolveSymbol)) && ! candidates.contains(symbol)) {
candidates.append(symbol);
}
candidates.append(symbol);
}
}
} else if (OperatorNameId *opId = name->asOperatorNameId()) {
......
......@@ -134,6 +134,10 @@ private:
QList<Scope *> buildVisibleScopes();
static bool isNameCompatibleWithIdentifier(Name *name, Identifier *id);
static bool maybeValidSymbol(Symbol *symbol,
ResolveMode mode,
const QList<Symbol *> &candidates);
private:
Control *_control;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment