diff --git a/duchain/builders/usebuilder.cpp b/duchain/builders/usebuilder.cpp --- a/duchain/builders/usebuilder.cpp +++ b/duchain/builders/usebuilder.cpp @@ -67,6 +67,9 @@ if (node->parameterType && node->parameterType->objectType) { buildNamespaceUses(node->parameterType->objectType); } + if (node->defaultValue) { + visitNodeWithExprVisitor(node->defaultValue); + } } void UseBuilder::visitClassImplements(ClassImplementsAst *node) diff --git a/duchain/expressionvisitor.cpp b/duchain/expressionvisitor.cpp --- a/duchain/expressionvisitor.cpp +++ b/duchain/expressionvisitor.cpp @@ -219,6 +219,14 @@ if (node->functionBody) { visitInnerStatementList(node->functionBody); } + if (node->returnType && node->returnType->objectType) { + NamespacedIdentifierAst* objectType = node->returnType->objectType; + QualifiedIdentifier id = identifierForNamespace(objectType, m_editor); + DeclarationPointer dec = findDeclarationImport(ClassDeclarationType, id); + + usingDeclaration(objectType->namespaceNameSequence->back()->element, dec); + buildNamespaceUses(objectType, id); + } //First try return typehint or phpdoc return typehint AbstractType::Ptr type = returnType(node->returnType, {}, m_editor, m_currentContext); @@ -233,6 +241,18 @@ forever { AbstractType::Ptr type = parameterType(it->element, {}, m_editor, m_currentContext); closureType->addArgument(type); + + if (it->element->parameterType && it->element->parameterType->objectType) { + NamespacedIdentifierAst* objectType = it->element->parameterType->objectType; + QualifiedIdentifier id = identifierForNamespace(objectType, m_editor); + DeclarationPointer dec = findDeclarationImport(ClassDeclarationType, id); + + usingDeclaration(objectType->namespaceNameSequence->back()->element, dec); + buildNamespaceUses(objectType, id); + } + if (it->element->defaultValue) { + visitExpr(it->element->defaultValue); + } if ( it->hasNext() ) { it = it->next; } else { diff --git a/duchain/tests/uses.h b/duchain/tests/uses.h --- a/duchain/tests/uses.h +++ b/duchain/tests/uses.h @@ -81,12 +81,14 @@ void useNamespace(); void lateStatic(); void closures(); + void closureTypehints(); void instanceof(); void classNameString(); void useTrait(); void exceptionFinally(); void returnTypeClassFunction(); void returnTypeFunction(); + void defaultValue(); }; } diff --git a/duchain/tests/uses.cpp b/duchain/tests/uses.cpp --- a/duchain/tests/uses.cpp +++ b/duchain/tests/uses.cpp @@ -1067,6 +1067,18 @@ QVERIFY(b->uses().isEmpty()); } +void TestUses::closureTypehints() { + TopDUContext* top = parse("localDeclarations().count(), 3); + Declaration* a = top->localDeclarations().at(0); + QCOMPARE(a->qualifiedIdentifier(), QualifiedIdentifier("a")); + compareUses(a, QList() << RangeInRevision(0, 32, 0, 33) << RangeInRevision(0, 39, 0, 40)); +} + void TestUses::instanceof() { // 0 1 2 3 4 5 @@ -1243,5 +1255,20 @@ compareUses(a, QList() << RangeInRevision(0, 30, 0, 31)); } +void TestUses::defaultValue() { + QByteArray method("localDeclarations().at(0); + QCOMPARE(a->identifier().toString(), QString("a")); + compareUses(a, QList() << RangeInRevision(0, 44, 0, 45)); + + Declaration *c = top->childContexts().at(0)->localDeclarations().at(0); + QCOMPARE(c->identifier().toString(), QString("C")); + compareUses(c, QList() << RangeInRevision(0, 47, 0, 48)); +} + }