diff --git a/duchain/builders/declarationbuilder.h b/duchain/builders/declarationbuilder.h --- a/duchain/builders/declarationbuilder.h +++ b/duchain/builders/declarationbuilder.h @@ -54,6 +54,7 @@ virtual void visitSwitchStmt(go::SwitchStmtAst* node); virtual void visitTypeCaseClause(go::TypeCaseClauseAst* node); virtual void visitExprCaseClause(go::ExprCaseClauseAst* node); + virtual void visitPrimaryExpr(go::PrimaryExprAst *node); /** * this handles variable declaration in select statements, e.g. diff --git a/duchain/builders/declarationbuilder.cpp b/duchain/builders/declarationbuilder.cpp --- a/duchain/builders/declarationbuilder.cpp +++ b/duchain/builders/declarationbuilder.cpp @@ -254,6 +254,18 @@ closeContext(); //body wrapper context } +void DeclarationBuilder::visitPrimaryExpr(go::PrimaryExprAst *node) +{ + if(node->signature && !node->convArg) // func type literal and not conversion. + { + buildFunction(node->signature, node->body); + } + else + { + go::DefaultVisitor::visitPrimaryExpr(node); + } +} + void DeclarationBuilder::visitMethodDeclaration(go::MethodDeclarationAst* node) { Declaration* declaration=0; diff --git a/duchain/tests/testduchain.h b/duchain/tests/testduchain.h --- a/duchain/tests/testduchain.h +++ b/duchain/tests/testduchain.h @@ -48,7 +48,8 @@ void test_unaryOps(); void test_typeAssertions(); void test_selectCases(); + void test_declareVariablesInParametersOfNestedFunction(); }; #endif \ No newline at end of file diff --git a/duchain/tests/testduchain.cpp b/duchain/tests/testduchain.cpp --- a/duchain/tests/testduchain.cpp +++ b/duchain/tests/testduchain.cpp @@ -167,6 +167,34 @@ QCOMPARE(declarations.size(), 0); } +void TestDuchain::test_declareVariablesInParametersOfNestedFunction() +{ + QString code("package main; func main() {\n" + "a := func(test1 int) { return test1 }\n" + "func(test2 int) { return test2 } (5)\n" + "pass(func(test3 int) {return test3 })\n}\n"); + auto mainContext = getMainContext(code); + DUChainReadLocker lock; + + auto firstFunctionContext = mainContext->childContexts().at(0); + auto declarations = firstFunctionContext->findDeclarations(QualifiedIdentifier("test1")); + QCOMPARE(declarations.size(), 1); + auto declaration = declarations.first(); + QCOMPARE(fastCast(declaration->abstractType().constData())->dataType(), uint(go::GoIntegralType::TypeInt)); + + auto secondFunctionContext = mainContext->childContexts().at(2); + declarations = secondFunctionContext->findDeclarations(QualifiedIdentifier("test2")); + QCOMPARE(declarations.size(), 1); + declaration = declarations.first(); + QCOMPARE(fastCast(declaration->abstractType().constData())->dataType(), uint(go::GoIntegralType::TypeInt)); + + auto thirdFunctionContext = mainContext->childContexts().at(4); + declarations = thirdFunctionContext->findDeclarations(QualifiedIdentifier("test3")); + QCOMPARE(declarations.size(), 1); + declaration = declarations.first(); + QCOMPARE(fastCast(declaration->abstractType().constData())->dataType(), uint(go::GoIntegralType::TypeInt)); +} + void TestDuchain::test_constants() { QString code("package main; const const1, const2 float32 = 1, 2; const ( const3, const4, const5 = 'a', 3, \"abc\"; ); ");