[kdev-python/listcontenttypes] /: Further tries to add a new type, but it crashes
Sven Brauch
svenbrauch at googlemail.com
Mon Jun 13 20:35:41 UTC 2011
Yeah sure, but I'll need to figure out how to do this first :)
Maybe you got an idea on this one:
I want to have a Type which is a structure type and can store two
additional properties. My current approach creates a
VariableLengthContainer class which inherits from StructureType (from
kdevelop), and then defines two additional properties (namely, the
type of the list contents) in a data class (same approach as in php).
This seems to be okay, however I need to be able to copy-construct
this type object from an existing StructureType object (because in
python, a list is an object, and as such has some methods, and those
need to be copied to that type). However, if I just call the default
copy-constructor, then the added data isn't being initialized and thus
it crashes (because it has non-initialized pointers around (like 0x41)
which should be 0 instead).
Any idea is welcome! This type stuff is really nasty if you're not
into it (like me).
Cheers,
Sven
2011/6/13 Niko Sams <niko.sams at gmail.com>:
> Sounds interesting. We need that for php too...
> once you get it working, could you please describe this features and maybe
> push common code to the platform (like the custom type if that makes sense).
>
> If you continue like that you will leave php support behind feature-wise ^^
>
> Niko
>
> On Mon, Jun 13, 2011 at 21:50, Sven Brauch <svenbrauch at googlemail.com> wrote:
>> Git commit c81a8078c0622ff882fce68847bf0d03e86c7917 by Sven Brauch.
>> Committed on 13/06/2011 at 21:52.
>> Pushed by brauch into branch 'listcontenttypes'.
>>
>> Further tries to add a new type, but it crashes
>>
>> M +1 -1 CMakeLists.txt
>> M +24 -1 duchain/declarationbuilder.cpp
>> M +3 -0 duchain/expressionvisitor.cpp
>> M +28 -1 duchain/tests/pyduchaintest.cpp
>> M +2 -0 duchain/tests/pyduchaintest.h
>> M +15 -1 duchain/types/variablelengthcontainer.cpp
>> M +33 -0 duchain/types/variablelengthcontainer.h
>> M +1 -1 pythonpythonparser.py
>>
>> http://commits.kde.org/kdev-python/c81a8078c0622ff882fce68847bf0d03e86c7917
>>
>> diff --git a/CMakeLists.txt b/CMakeLists.txt
>> index a217a2c..6ce8575 100644
>> --- a/CMakeLists.txt
>> +++ b/CMakeLists.txt
>> @@ -9,7 +9,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${kdevpython_SOURCE_DIR}/cmake/)
>> find_package(KDE4 REQUIRED)
>> find_package(KDevPlatform 1.2.60 REQUIRED)
>>
>> -set(CMAKE_CXX_FLAGS_DEBUG -Wfatal-errors -Wall)
>> +set(CMAKE_CXX_FLAGS_DEBUG "-Wfatal-errors -Wall")
>>
>> # then, build the plugin
>> include_directories(
>> diff --git a/duchain/declarationbuilder.cpp b/duchain/declarationbuilder.cpp
>> index 918a22e..0e025e9 100644
>> --- a/duchain/declarationbuilder.cpp
>> +++ b/duchain/declarationbuilder.cpp
>> @@ -53,6 +53,7 @@
>> #include "expressionvisitor.h"
>> #include <interfaces/foregroundlock.h>
>> #include "helpers.h"
>> +#include "types/variablelengthcontainer.h"
>>
>>
>> using namespace KTextEditor;
>> @@ -407,6 +408,18 @@ void DeclarationBuilder::visitAssignment(AssignmentAst* node)
>> tupleElementType = AbstractType::Ptr(new IntegralType(IntegralType::TypeMixed));
>> tupleElementDeclaration = 0;
>> }
>> + /** DEBUG **/
>> + if ( tupleElementType ) {
>> + VariableLengthContainer* d = dynamic_cast<VariableLengthContainer*>(tupleElementType.unsafeData());
>> + if ( d ) {
>> + DUChainReadLocker lock(DUChain::lock());
>> + kDebug() << "Got container type for declaration creation: " << tupleElementType << d->contentType();
>> + if ( d->contentType() ) {
>> + kDebug() << "Content type: " << d->contentType()->toString();
>> + }
>> + }
>> + }
>> + /** END DEBUG **/
>> i += 1;
>> setLastType(tupleElementType); // TODO fix this for x, y = a, b, i.e. if node->value->astType == TupleAstType
>> if ( target->astType == Ast::NameAstType ) {
>> @@ -418,7 +431,17 @@ void DeclarationBuilder::visitAssignment(AssignmentAst* node)
>> }
>> }
>> else {
>> - visitVariableDeclaration<Declaration>(target);
>> + DUChainWriteLocker lock(DUChain::lock());
>> + Declaration* dec = visitVariableDeclaration<Declaration>(target);
>> + dec->setAbstractType(tupleElementType);
>> + /** DEBUG **/
>> + if ( tupleElementType ) {
>> + VariableLengthContainer* type = dynamic_cast<VariableLengthContainer*>(dec->abstractType().unsafeData());
>> + kDebug() << "type is: " << dec->abstractType().unsafeData() << type << dynamic_cast<VariableLengthContainer*>(tupleElementType.unsafeData());
>> + kDebug() << "indexed: " << tupleElementType->indexed().hash() << "<>" << dec->indexedType().hash();
>> + Q_ASSERT((dynamic_cast<VariableLengthContainer*>(tupleElementType.unsafeData()) == 0 ) xor ( dec->abstractType().unsafeData() == 0));
>> + }
>> + /** END DEBUG **/
>> }
>> }
>> if ( target->astType == Ast::AttributeAstType ) {
>> diff --git a/duchain/expressionvisitor.cpp b/duchain/expressionvisitor.cpp
>> index 576fd03..1b71238 100644
>> --- a/duchain/expressionvisitor.cpp
>> +++ b/duchain/expressionvisitor.cpp
>> @@ -266,8 +266,11 @@ template<typename T> TypePtr<T> ExpressionVisitor::typeObjectForIntegralType(QSt
>> builtinListTypes << "list" << "dict";
>> if ( builtinListTypes.contains(typeDescriptor) && decl ) {
>> // return something which can hold a content type
>> + kDebug() << "Returning container type object";
>> VariableLengthContainer* container = new VariableLengthContainer(type);
>> type = AbstractType::Ptr(container);
>> + VariableLengthContainer* t = dynamic_cast<VariableLengthContainer*>(type.unsafeData());
>> + Q_ASSERT(t);
>> }
>> return type.cast<T>();
>> }
>> diff --git a/duchain/tests/pyduchaintest.cpp b/duchain/tests/pyduchaintest.cpp
>> index 318369d..f6dd46f 100644
>> --- a/duchain/tests/pyduchaintest.cpp
>> +++ b/duchain/tests/pyduchaintest.cpp
>> @@ -42,6 +42,7 @@
>> #include <astbuilder.h>
>> #include <language/duchain/aliasdeclaration.h>
>> #include <KStandardDirs>
>> +#include <types/variablelengthcontainer.h>
>>
>> QTEST_MAIN(PyDUChainTest)
>>
>> @@ -62,6 +63,8 @@ void PyDUChainTest::initShell()
>>
>> KUrl doc_url = KUrl(KStandardDirs::locate("data", "kdevpythonsupport/documentation_files/builtindocumentation.py"));
>> doc_url.cleanPath(KUrl::SimplifyDirSeparators);
>> +
>> + kDebug() << doc_url;
>>
>> DUChain::self()->updateContextForUrl(IndexedString(doc_url), KDevelop::TopDUContext::AllDeclarationsContextsAndUses);
>> DUChain::self()->waitForUpdate(IndexedString(doc_url), KDevelop::TopDUContext::AllDeclarationsContextsAndUses);
>> @@ -493,6 +496,30 @@ void PyDUChainTest::testFunctionArgs()
>> DUContext* funcBodyCtx = ctx->childContexts().last();
>> QCOMPARE(funcBodyCtx->type(), DUContext::Other);
>> QVERIFY(funcBodyCtx->owner());
>> - QEXPECT_FAIL("", "fixme: re-use argument declaration", Continue);
>> QVERIFY(funcBodyCtx->localDeclarations().isEmpty());
>> }
>> +
>> +void PyDUChainTest::testContainerTypes()
>> +{
>> + QFETCH(QString, code);
>> + QFETCH(QString, contenttype);
>> + ReferencedTopDUContext ctx = parse(code.toAscii());
>> + QVERIFY(ctx);
>> +
>> + DUChainReadLocker lock(DUChain::lock());
>> + QList<Declaration*> decls = ctx->findDeclarations(QualifiedIdentifier("checkme"));
>> + QVERIFY(decls.length() > 0);
>> + VariableLengthContainer* type = dynamic_cast<VariableLengthContainer*>(decls.first()->abstractType().unsafeData());
>> + kDebug() << "type is: " << decls.first()->abstractType().unsafeData()->toString();
>> + QVERIFY(type);
>> + QVERIFY(type->contentType()->toString() == contenttype);
>> +}
>> +
>> +void PyDUChainTest::testContainerTypes_data()
>> +{
>> + QTest::addColumn<QString>("code");
>> + QTest::addColumn<QString>("contenttype");
>> +
>> + QTest::newRow("list_of_int") << "checkme = [1, 2, 3]" << "float";
>> +}
>> +
>> diff --git a/duchain/tests/pyduchaintest.h b/duchain/tests/pyduchaintest.h
>> index 2e166df..621b85f 100644
>> --- a/duchain/tests/pyduchaintest.h
>> +++ b/duchain/tests/pyduchaintest.h
>> @@ -64,6 +64,8 @@ class PyDUChainTest : public QObject
>> void testFunctionArgs();
>> void testAutocompletionFlickering();
>> void updateReady(KDevelop::IndexedString url, KDevelop::ReferencedTopDUContext topContext);
>> + void testContainerTypes();
>> + void testContainerTypes_data();
>>
>> // void testFunctionStuff();
>> // void testFunctionStuff_data();
>> diff --git a/duchain/types/variablelengthcontainer.cpp b/duchain/types/variablelengthcontainer.cpp
>> index 48d6869..3001cda 100644
>> --- a/duchain/types/variablelengthcontainer.cpp
>> +++ b/duchain/types/variablelengthcontainer.cpp
>> @@ -16,6 +16,8 @@
>> along with this program. If not, see <http://www.gnu.org/licenses/>.
>> **/
>>
>> +#include <language/duchain/types/typeregister.h>
>> +
>> #include "variablelengthcontainer.h"
>> #include "helpers.h"
>>
>> @@ -23,7 +25,9 @@ using namespace KDevelop;
>>
>> namespace Python {
>>
>> -VariableLengthContainer::VariableLengthContainer(const StructureType& rhs) : StructureType(rhs)
>> +REGISTER_TYPE(VariableLengthContainer);
>> +
>> +VariableLengthContainer::VariableLengthContainer(const StructureType& rhs) : StructureType(rhs), m_contentType(0), m_keyType(0)
>> {
>>
>> }
>> @@ -53,4 +57,14 @@ AbstractType::Ptr Python::VariableLengthContainer::keyType()
>> return m_keyType;
>> }
>>
>> +KDevelop::AbstractType* VariableLengthContainer::clone() const
>> +{
>> + return new VariableLengthContainer(*this);
>> +}
>> +
>> +uint VariableLengthContainer::hash() const
>> +{
>> + return StructureType::hash() + ( m_contentType ? m_contentType->hash() : 0 ) + ( m_keyType ? m_keyType->hash() : 0 );
>> +}
>> +
>> }
>> diff --git a/duchain/types/variablelengthcontainer.h b/duchain/types/variablelengthcontainer.h
>> index 553c304..6c11766 100644
>> --- a/duchain/types/variablelengthcontainer.h
>> +++ b/duchain/types/variablelengthcontainer.h
>> @@ -21,11 +21,29 @@
>> #define VARIABLELENGTHCONTAINER_H
>>
>> #include <language/duchain/types/structuretype.h>
>> +#include <language/duchain/types/typesystemdata.h>
>> +
>> #include "pythonduchainexport.h"
>>
>> using namespace KDevelop;
>>
>> namespace Python {
>> +
>> +class KDEVPYTHONDUCHAIN_EXPORT VariableLengthContainerData : public KDevelop::StructureTypeData
>> +{
>> +public:
>> + /// Constructor
>> + VariableLengthContainerData()
>> + : KDevelop::StructureTypeData()
>> + {
>> + }
>> + /// Copy constructor. \param rhs data to copy
>> + VariableLengthContainerData( const StructureTypeData& rhs )
>> + : KDevelop::StructureTypeData(rhs)
>> + {
>> + }
>> +};
>> +
>>
>> /**
>> * Describes something like a python list which is a list, but has a second type,
>> @@ -34,6 +52,8 @@ namespace Python {
>> class KDEVPYTHONDUCHAIN_EXPORT VariableLengthContainer : public KDevelop::StructureType
>> {
>> public:
>> + typedef TypePtr<VariableLengthContainer> Ptr;
>> +
>> VariableLengthContainer(const StructureType& rhs);
>> VariableLengthContainer(const AbstractType::Ptr copyFrom);
>> AbstractType::Ptr m_contentType;
>> @@ -42,6 +62,19 @@ public:
>> AbstractType::Ptr m_keyType;
>> AbstractType::Ptr keyType();
>> void addKeyType(AbstractType::Ptr typeToAdd);
>> + virtual AbstractType* clone() const;
>> + virtual uint hash() const;
>> +
>> + enum {
>> +#warning check identity value (61)
>> + Identity = 61
>> + };
>> +
>> + typedef VariableLengthContainerData Data;
>> + typedef KDevelop::StructureType BaseType;
>> +
>> +protected:
>> + TYPE_DECLARE_DATA(VariableLengthContainer);
>> };
>>
>> }
>> diff --git a/pythonpythonparser.py b/pythonpythonparser.py
>> index 91a54f7..2a854bf 100755
>> --- a/pythonpythonparser.py
>> +++ b/pythonpythonparser.py
>> @@ -1,4 +1,4 @@
>> -#!/usr/bin/env python2.6
>> +#!/usr/bin/env python2.7
>> # -*- coding: utf-8 -*-
>>
>> #
>>
>
More information about the KDevelop-devel
mailing list