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

Niko Sams niko.sams at gmail.com
Mon Jun 13 21:01:09 UTC 2011


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