C++: fixed operator arrow of nested class of enclosing template

Fixed:
* code completion
* highlighting
* find usage
* follow symbol

Task-number: QTCREATORBUG-9005
Change-Id: I3fcc2638482ca1071c1aa7b6aab0d4dd128595bb
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
This commit is contained in:
Przemyslaw Gorszkowski
2013-04-04 12:07:44 +02:00
committed by Erik Verbruggen
parent 7543a08582
commit 9c2a352027
3 changed files with 56 additions and 14 deletions

View File

@@ -1106,29 +1106,26 @@ bool ClassOrNamespace::NestedClassInstantiator::isInstantiateNestedClassNeeded(c
bool ClassOrNamespace::NestedClassInstantiator::containsTemplateType(Declaration *declaration) const
{
Type *memberType = declaration->type().type();
NamedType *memberNamedType = findMemberNamedType(memberType);
if (memberNamedType) {
const Name *name = memberNamedType->name();
if (_subst.contains(name))
return true;
}
return false;
NamedType *namedType = findNamedType(memberType);
return namedType && _subst.contains(namedType->name());
}
bool ClassOrNamespace::NestedClassInstantiator::containsTemplateType(Function * /*function*/) const
bool ClassOrNamespace::NestedClassInstantiator::containsTemplateType(Function *function) const
{
//TODO: make implementation
return false;
Type *returnType = function->returnType().type();
NamedType *namedType = findNamedType(returnType);
return namedType && _subst.contains(namedType->name());
//TODO: in future we will need also check function arguments, for now returned value is enough
}
NamedType *ClassOrNamespace::NestedClassInstantiator::findMemberNamedType(Type *memberType) const
NamedType *ClassOrNamespace::NestedClassInstantiator::findNamedType(Type *memberType) const
{
if (NamedType *namedType = memberType->asNamedType())
return namedType;
else if (PointerType *pointerType = memberType->asPointerType())
return findMemberNamedType(pointerType->elementType().type());
return findNamedType(pointerType->elementType().type());
else if (ReferenceType *referenceType = memberType->asReferenceType())
return findMemberNamedType(referenceType->elementType().type());
return findNamedType(referenceType->elementType().type());
return 0;
}

View File

@@ -152,7 +152,7 @@ private:
bool isInstantiateNestedClassNeeded(const QList<Symbol *> &symbols) const;
bool containsTemplateType(Declaration *declaration) const;
bool containsTemplateType(Function *function) const;
NamedType *findMemberNamedType(Type *memberType) const;
NamedType *findNamedType(Type *memberType) const;
QSet<ClassOrNamespace *> _alreadyConsideredNestedClassInstantiations;
CreateBindings *_factory;

View File

@@ -95,6 +95,7 @@ private Q_SLOTS:
// templates
void instantiateTemplateWithNestedClass();
void operatorAsteriskOfNestedClassOfTemplateClass_QTCREATORBUG9006();
void operatorArrowOfNestedClassOfTemplateClass_QTCREATORBUG9005();
};
void tst_FindUsages::inlineMethod()
@@ -490,5 +491,49 @@ void tst_FindUsages::operatorAsteriskOfNestedClassOfTemplateClass_QTCREATORBUG90
QCOMPARE(findUsages.usages().size(), 2);
}
void tst_FindUsages::operatorArrowOfNestedClassOfTemplateClass_QTCREATORBUG9005()
{
const QByteArray src = "\n"
"struct Foo { int foo; };\n"
"\n"
"template<class T>\n"
"struct Outer\n"
"{\n"
" struct Nested\n"
" {\n"
" T *operator->() { return 0; }\n"
" };\n"
"};\n"
"\n"
"void bug()\n"
"{\n"
" Outer<Foo>::Nested nested;\n"
" nested->foo;\n"
"}\n"
;
Document::Ptr doc = Document::create("operatorArrowOfNestedClassOfTemplateClass_QTCREATORBUG9005");
doc->setUtf8Source(src);
doc->parse();
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
QCOMPARE(doc->globalSymbolCount(), 3U);
Snapshot snapshot;
snapshot.insert(doc);
Class *classFoo = doc->globalSymbolAt(0)->asClass();
QVERIFY(classFoo);
QCOMPARE(classFoo->memberCount(), 1U);
Declaration *fooDeclaration = classFoo->memberAt(0)->asDeclaration();
QVERIFY(fooDeclaration);
QCOMPARE(fooDeclaration->name()->identifier()->chars(), "foo");
FindUsages findUsages(src, doc, snapshot);
findUsages(fooDeclaration);
QCOMPARE(findUsages.usages().size(), 2);
}
QTEST_APPLESS_MAIN(tst_FindUsages)
#include "tst_findusages.moc"