[kdev-python/listcontenttypes] /: Further tries to add a new type, but it crashes

Sven Brauch svenbrauch at googlemail.com
Mon Jun 13 21:27:47 UTC 2011


There is an IntegralType for List, but it'll be hackish to add methods
to it, won't it? So I just created a class "List" in my
builtinfunctions.py file (same as you have for php).

What exactly do I have to call to initialize that data class? If I
copy data from an existing StructureType, I cannot use createData(),
can I?

Bye,
Sven

2011/6/13 Niko Sams <niko.sams at gmail.com>:
> is there no ArrayType or ListType that does that already?
> Or - what do you need from StructureType?
> At least in Php an a ListType would be ok, but maybe python is different
> as the list is an object and has default methods and everything...
>
> ...copying the data should not be too difficult, it's just a matter of
> copying the
> code from a similar type I guess.
>
> Niko
>
> On Mon, Jun 13, 2011 at 22:35, Sven Brauch <svenbrauch at googlemail.com> wrote:
>> 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