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 bool ClassOrNamespace::NestedClassInstantiator::containsTemplateType(Declaration *declaration) const
{ {
Type *memberType = declaration->type().type(); Type *memberType = declaration->type().type();
NamedType *memberNamedType = findMemberNamedType(memberType); NamedType *namedType = findNamedType(memberType);
if (memberNamedType) { return namedType && _subst.contains(namedType->name());
const Name *name = memberNamedType->name();
if (_subst.contains(name))
return true;
}
return false;
} }
bool ClassOrNamespace::NestedClassInstantiator::containsTemplateType(Function * /*function*/) const bool ClassOrNamespace::NestedClassInstantiator::containsTemplateType(Function *function) const
{ {
//TODO: make implementation Type *returnType = function->returnType().type();
return false; 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()) if (NamedType *namedType = memberType->asNamedType())
return namedType; return namedType;
else if (PointerType *pointerType = memberType->asPointerType()) else if (PointerType *pointerType = memberType->asPointerType())
return findMemberNamedType(pointerType->elementType().type()); return findNamedType(pointerType->elementType().type());
else if (ReferenceType *referenceType = memberType->asReferenceType()) else if (ReferenceType *referenceType = memberType->asReferenceType())
return findMemberNamedType(referenceType->elementType().type()); return findNamedType(referenceType->elementType().type());
return 0; return 0;
} }

View File

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

View File

@@ -95,6 +95,7 @@ private Q_SLOTS:
// templates // templates
void instantiateTemplateWithNestedClass(); void instantiateTemplateWithNestedClass();
void operatorAsteriskOfNestedClassOfTemplateClass_QTCREATORBUG9006(); void operatorAsteriskOfNestedClassOfTemplateClass_QTCREATORBUG9006();
void operatorArrowOfNestedClassOfTemplateClass_QTCREATORBUG9005();
}; };
void tst_FindUsages::inlineMethod() void tst_FindUsages::inlineMethod()
@@ -490,5 +491,49 @@ void tst_FindUsages::operatorAsteriskOfNestedClassOfTemplateClass_QTCREATORBUG90
QCOMPARE(findUsages.usages().size(), 2); 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) QTEST_APPLESS_MAIN(tst_FindUsages)
#include "tst_findusages.moc" #include "tst_findusages.moc"