C++: improve support for anonymous classes

Fix:
* highlighting
* find usages
* follow symbol
* code completion

Task-number: QTCREATORBUG-6497
Task-number: QTCREATORBUG-8963
Task-number: QTCREATORBUG-3610
Task-number: QTCREATORBUG-7579

Change-Id: I3dcaf1c515d0199c3e6bee72284fbb40064686ee
Reviewed-by: Petar Perisin <petar.perisin@gmail.com>
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
This commit is contained in:
Przemyslaw Gorszkowski
2013-04-10 23:30:18 +02:00
committed by Erik Verbruggen
parent a2b2857b44
commit 080bf4ecb8
27 changed files with 341 additions and 7 deletions

View File

@@ -60,7 +60,7 @@ static void addNames(const Name *name, QList<const Name *> *names, bool addAllNa
else if (const QualifiedNameId *q = name->asQualifiedNameId()) {
addNames(q->base(), names);
addNames(q->name(), names, addAllNames);
} else if (addAllNames || name->isNameId() || name->isTemplateNameId()) {
} else if (addAllNames || name->isNameId() || name->isTemplateNameId() || name->isAnonymousNameId()) {
names->append(name);
}
}
@@ -716,7 +716,7 @@ ClassOrNamespace *ClassOrNamespace::lookupType_helper(const Name *name,
} else if (! processed->contains(this)) {
processed->insert(this);
if (name->isNameId() || name->isTemplateNameId()) {
if (name->isNameId() || name->isTemplateNameId() || name->isAnonymousNameId()) {
flush();
foreach (Symbol *s, symbols()) {
@@ -798,10 +798,26 @@ ClassOrNamespace *ClassOrNamespace::findSpecializationWithPointer(const Template
ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespace *origin)
{
Q_ASSERT(name != 0);
Q_ASSERT(name->isNameId() || name->isTemplateNameId());
Q_ASSERT(name->isNameId() || name->isTemplateNameId() || name->isAnonymousNameId());
const_cast<ClassOrNamespace *>(this)->flush();
const AnonymousNameId *anonymousNameId = name->asAnonymousNameId();
if (anonymousNameId) {
QHash<const AnonymousNameId *, ClassOrNamespace *>::const_iterator cit
= _anonymouses.find(anonymousNameId);
if (cit != _anonymouses.end()) {
return cit.value();
} else {
ClassOrNamespace *newAnonymous = _factory->allocClassOrNamespace(this);
#ifdef DEBUG_LOOKUP
newAnonymous->_name = anonymousNameId;
#endif // DEBUG_LOOKUP
_anonymouses[anonymousNameId] = newAnonymous;
return newAnonymous;
}
}
Table::const_iterator it = _classOrNamespaces.find(name);
if (it == _classOrNamespaces.end())
return 0;
@@ -1201,7 +1217,7 @@ ClassOrNamespace *ClassOrNamespace::findOrCreateType(const Name *name, ClassOrNa
return findOrCreateType(q->base(), origin)->findOrCreateType(q->name(), origin);
} else if (name->isNameId() || name->isTemplateNameId()) {
} else if (name->isNameId() || name->isTemplateNameId() || name->isAnonymousNameId()) {
ClassOrNamespace *e = nestedType(name, origin);
if (! e) {
@@ -1470,7 +1486,7 @@ bool CreateBindings::visit(NamespaceAlias *a)
return false;
} else if (ClassOrNamespace *e = _currentClassOrNamespace->lookupType(a->namespaceName())) {
if (a->name()->isNameId() || a->name()->isTemplateNameId())
if (a->name()->isNameId() || a->name()->isTemplateNameId() || a->name()->isAnonymousNameId())
_currentClassOrNamespace->addNestedType(a->name(), e);
} else if (false) {

View File

@@ -131,6 +131,7 @@ private:
QSharedPointer<Control> _control;
TemplateNameIdTable _specializations;
QMap<const TemplateNameId *, ClassOrNamespace *> _instantiations;
QHash<const AnonymousNameId *, ClassOrNamespace *> _anonymouses;
QHash<Internal::FullyQualifiedName, Symbol *> *_scopeLookupCache;

View File

@@ -268,3 +268,8 @@ void NamePrettyPrinter::visit(const SelectorNameId *name)
}
}
}
void NamePrettyPrinter::visit(const AnonymousNameId *name)
{
_name = QString(QLatin1String("Anonymous:%1")).arg(name->classTokenIndex());
}

View File

@@ -57,6 +57,7 @@ protected:
virtual void visit(const ConversionNameId *name);
virtual void visit(const QualifiedNameId *name);
virtual void visit(const SelectorNameId *name);
virtual void visit(const AnonymousNameId *name);
private:
const Overview *_overview;