forked from qt-creator/qt-creator
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:
committed by
Erik Verbruggen
parent
7543a08582
commit
9c2a352027
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
@@ -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"
|
||||||
|
Reference in New Issue
Block a user