diff --git a/duchain/expressionvisitor.cpp b/duchain/expressionvisitor.cpp --- a/duchain/expressionvisitor.cpp +++ b/duchain/expressionvisitor.cpp @@ -343,6 +343,13 @@ } } else if (node->varFunctionName) { //static function call foo::$bar() + } else if (node->expr) { + //static function call foo::{expr}() + const QualifiedIdentifier id = identifierForNamespace(node->stringFunctionNameOrClass, m_editor); + DeclarationPointer dec = findDeclarationImport(ClassDeclarationType, id); + usingDeclaration(node->stringFunctionNameOrClass->namespaceNameSequence->back()->element, dec); + buildNamespaceUses(node->stringFunctionNameOrClass, id); + m_result.setDeclaration(dec); } else { //global function call foo(); const QualifiedIdentifier id = identifierForNamespace(node->stringFunctionNameOrClass, m_editor); diff --git a/duchain/tests/duchain.h b/duchain/tests/duchain.h --- a/duchain/tests/duchain.h +++ b/duchain/tests/duchain.h @@ -151,6 +151,7 @@ void testTodoExtractor(); void useThisAsArray(); void wrongUseOfThisAsArray(); + void staticFunctionClassPhp54(); }; } diff --git a/duchain/tests/duchain.cpp b/duchain/tests/duchain.cpp --- a/duchain/tests/duchain.cpp +++ b/duchain/tests/duchain.cpp @@ -2998,3 +2998,25 @@ QCOMPARE(top->problems().size(),1); } + +void TestDUChain::staticFunctionClassPhp54() +{ + QByteArray method("problems().isEmpty()); + QCOMPARE(top->localDeclarations().count(),1); + + Declaration* dec = top->localDeclarations().at(0); + ClassDeclaration* classDec = dynamic_cast(dec); + QCOMPARE(classDec->uses().count(),1); +} diff --git a/parser/php.g b/parser/php.g --- a/parser/php.g +++ b/parser/php.g @@ -650,6 +650,7 @@ ( stringFunctionName=identifier LPAREN stringParameterList=functionCallParameterList RPAREN | varFunctionName=variableWithoutObjects LPAREN stringParameterList=functionCallParameterList RPAREN + | LBRACE (expr=expr) RBRACE LPAREN stringParameterList=functionCallParameterList RPAREN ) ) | varFunctionName=variableWithoutObjects LPAREN varParameterList=functionCallParameterList RPAREN