[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