diff --git a/duchain/builders/typebuilder.h b/duchain/builders/typebuilder.h --- a/duchain/builders/typebuilder.h +++ b/duchain/builders/typebuilder.h @@ -115,6 +115,7 @@ KDevelop::AbstractType::Ptr injectParseType(QString type, AstNode* node); KDevelop::AbstractType::Ptr parseType(QString type, AstNode* node); + KDevelop::AbstractType::Ptr parseSimpleType(QString type, AstNode* node); KDevelop::AbstractType::Ptr parseDocComment(AstNode* node, const QString& docCommentName); QList parseDocCommentParams(AstNode* node); }; diff --git a/duchain/builders/typebuilder.cpp b/duchain/builders/typebuilder.cpp --- a/duchain/builders/typebuilder.cpp +++ b/duchain/builders/typebuilder.cpp @@ -26,8 +26,8 @@ #include #include #include +#include #include "../declarations/classdeclaration.h" -#include "../types/indexedcontainer.h" #include "../types/integraltypeextended.h" #include "../types/structuretype.h" #include @@ -57,8 +57,35 @@ AbstractType::Ptr TypeBuilder::parseType(QString type, AstNode* node) { - uint iType = 0; type = type.trimmed(); + + if (type.contains('|')) { + QList types; + foreach (const QString& t, type.split('|')) { + AbstractType::Ptr subType = parseType(t, node); + if (!(IntegralType::Ptr::dynamicCast(subType) && IntegralType::Ptr::staticCast(subType)->dataType() == IntegralType::TypeMixed)) { + types << parseType(t, node); + } + } + UnsureType::Ptr ret(new UnsureType()); + foreach (const AbstractType::Ptr& t, types) { + ret->addType(t->indexed()); + } + return AbstractType::Ptr::staticCast(ret); + } + + if (type.endsWith(QLatin1String("[]"))) { + KDevelop::ArrayType* a_type = new KDevelop::ArrayType(); + a_type->setElementType(parseSimpleType(type.left(type.length() - 2), node)); + return AbstractType::Ptr(a_type); + } else { + return parseSimpleType(type, node); + } +} + +AbstractType::Ptr TypeBuilder::parseSimpleType(QString type, AstNode* node) +{ + uint iType = 0; if (!type.compare(QLatin1String("int"), Qt::CaseInsensitive) || !type.compare(QLatin1String("integer"), Qt::CaseInsensitive)) { iType = IntegralType::TypeInt; } else if (!type.compare(QLatin1String("float"), Qt::CaseInsensitive) || !type.compare(QLatin1String("double"), Qt::CaseInsensitive)) { @@ -101,23 +128,6 @@ if (decl && decl->abstractType()) { return decl->abstractType(); } - if (type.contains('|')) { - QList types; - foreach (const QString& t, type.split('|')) { - AbstractType::Ptr subType = parseType(t, node); - if (!(IntegralType::Ptr::dynamicCast(subType) && IntegralType::Ptr::staticCast(subType)->dataType() == IntegralType::TypeMixed)) { - types << parseType(t, node); - } - } - if (!type.isEmpty()) { - UnsureType::Ptr ret(new UnsureType()); - foreach (const AbstractType::Ptr& t, types) { - ret->addType(t->indexed()); - } - //qCDebug(DUCHAIN) << type << ret->toString(); - return AbstractType::Ptr::staticCast(ret); - } - } iType = IntegralType::TypeMixed; } AbstractType::Ptr ret(new IntegralType(iType)); @@ -572,7 +582,11 @@ } } } + } else if ( ArrayType::Ptr a_type = ArrayType::Ptr::dynamicCast(v.result().type()) ) { + injectType(a_type->elementType()); + foundType = true; } + if (!foundType) { injectType(AbstractType::Ptr(new IntegralType(IntegralType::TypeMixed))); } diff --git a/duchain/helper.cpp b/duchain/helper.cpp --- a/duchain/helper.cpp +++ b/duchain/helper.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -44,7 +45,6 @@ #include "declarations/classdeclaration.h" #include "declarations/classmethoddeclaration.h" #include "declarations/functiondeclaration.h" -#include "types/indexedcontainer.h" #include "types/integraltypeextended.h" #include "expressionparser.h" #include "expressionvisitor.h" @@ -570,9 +570,8 @@ } if (node->isVariadic != -1) { - auto *container = new IndexedContainer(); - container->addEntry(type); - container->setPrettyName(IndexedString("array")); + auto *container = new KDevelop::ArrayType(); + container->setElementType(type); type = AbstractType::Ptr(container); } diff --git a/duchain/navigation/declarationnavigationcontext.cpp b/duchain/navigation/declarationnavigationcontext.cpp --- a/duchain/navigation/declarationnavigationcontext.cpp +++ b/duchain/navigation/declarationnavigationcontext.cpp @@ -30,8 +30,8 @@ #include #include #include +#include -#include "../types/indexedcontainer.h" #include "../declarations/classdeclaration.h" #include #include @@ -198,9 +198,9 @@ if (argDec && argDec->isVariadic()) { AbstractType::Ptr variadicType; - const auto indexed = argType.cast(); - if (indexed && indexed->typesCount() == 1) { - variadicType = indexed->typeAt(0).abstractType(); + const auto a_type = argType.cast(); + if (a_type) { + variadicType = a_type->elementType(); } else { variadicType = AbstractType::Ptr(new IntegralType(IntegralType::TypeMixed)); } diff --git a/duchain/tests/duchain.h b/duchain/tests/duchain.h --- a/duchain/tests/duchain.h +++ b/duchain/tests/duchain.h @@ -139,6 +139,7 @@ void foreachIterator2(); void foreachIterator3(); void foreachIterator4(); + void foreachArray(); void returnThis(); void unsureReturnType(); void unsureReturnType2(); diff --git a/duchain/tests/duchain.cpp b/duchain/tests/duchain.cpp --- a/duchain/tests/duchain.cpp +++ b/duchain/tests/duchain.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -44,7 +45,6 @@ #include "../types/structuretype.h" #include "../types/integraltypeextended.h" -#include "../types/indexedcontainer.h" #include @@ -1012,11 +1012,9 @@ AbstractType::Ptr arg = fun->arguments().first(); QVERIFY(arg); - QVERIFY(arg.cast()); - QCOMPARE(arg.cast()->typesCount(), 1); - QCOMPARE(arg.cast()->prettyName().str(), QStringLiteral("array")); + QVERIFY(arg.cast()); - AbstractType::Ptr typehint = arg.cast()->typeAt(0).abstractType(); + AbstractType::Ptr typehint = arg.cast()->elementType(); QVERIFY(typehint); QVERIFY(IntegralType::Ptr::dynamicCast(typehint)); QVERIFY(IntegralType::Ptr::dynamicCast(typehint)->dataType() == IntegralType::TypeMixed); @@ -1039,11 +1037,9 @@ AbstractType::Ptr arg = fun->arguments().first(); QVERIFY(arg); - QVERIFY(arg.cast()); - QCOMPARE(arg.cast()->typesCount(), 1); - QCOMPARE(arg.cast()->prettyName().str(), QStringLiteral("array")); + QVERIFY(arg.cast()); - AbstractType::Ptr typehint = arg.cast()->typeAt(0).abstractType(); + AbstractType::Ptr typehint = arg.cast()->elementType(); QVERIFY(typehint); QCOMPARE(typehint->toString(), QStringLiteral("A")); } @@ -2739,6 +2735,29 @@ QCOMPARE(aDec->uses().begin()->size(), 4); } +void TestDUChain::foreachArray() +{ + { + QByteArray code = "childContexts().last(); + QCOMPARE(barContext->localScopeIdentifier(), QualifiedIdentifier("bar")); + + Declaration* eDec = barContext->localDeclarations().first(); + QCOMPARE(eDec->qualifiedIdentifier(), QualifiedIdentifier("bar::e")); + QVERIFY(eDec->type()); + QCOMPARE(eDec->type()->qualifiedIdentifier(), QualifiedIdentifier("foo")); + } +} + void TestDUChain::returnThis() { QByteArray code("