diff options
author | Marcelo Lira <marcelo.lira@openbossa.org> | 2011-07-20 11:53:01 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-09 19:10:18 -0300 |
commit | e486e0bbe2065bbc228f84f93178e0636475021b (patch) | |
tree | 68477e77776beb0c4c1766b186e0072a35679876 | |
parent | b3644ccd1f52073ed70ce8b6e0ed4f58a07632d7 (diff) |
Added default constructor option for value types.
The unit test is in place and the 'value-type' tag documentation was
update with information about the 'default-constructor' attribute.
Reviewed by Hugo Parente <hugo.lima@openbossa.org>
Reviewed by Luciano Wolf <luciano.wolf@openbossa.org>
-rw-r--r-- | doc/typesystem_specifying_types.rst | 13 | ||||
-rw-r--r-- | tests/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/testvaluetypedefaultctortag.cpp | 57 | ||||
-rw-r--r-- | tests/testvaluetypedefaultctortag.h | 36 | ||||
-rw-r--r-- | typesystem.cpp | 41 | ||||
-rw-r--r-- | typesystem.h | 4 |
6 files changed, 145 insertions, 7 deletions
diff --git a/doc/typesystem_specifying_types.rst b/doc/typesystem_specifying_types.rst index cadddfe99..d5a4ef2d9 100644 --- a/doc/typesystem_specifying_types.rst +++ b/doc/typesystem_specifying_types.rst @@ -94,6 +94,11 @@ primitive-type and "long long" become "long" but we should prefer the "qint64" version. For this reason we mark "long long" with preferred-conversion="no". + The *optional* **default-constructor** specifies the minimal constructor + call to build one value of the primitive-type. This is not needed when the + primitive-type may be built with a default constructor (the one without + arguments). + The *optional* **preferred-conversion** attribute tells how to build a default instance of the primitive type. It should be a constructor call capable of creating a instance of the primitive type. Example: a class "Foo" could have @@ -212,6 +217,7 @@ value-type copyable="yes | no" hash-function="..." stream="yes | no" + default-constructor="..." revision="..." /> </typesystem> @@ -226,6 +232,13 @@ value-type The *optional* **since** value is used to specify the API version of this type. + The *optional* **default-constructor** specifies the minimal constructor + call to build one instance of the value-type. This is not needed when the + value-type may be built with a default constructor (the one without arguments). + Usually a code generator may guess a minimal constructor for a value-type based + on its constructor signatures, thus **default-constructor** is used only in + very odd cases. + The **revision** attribute can be used to specify a revision for each type, easing the production of ABI compatible bindings. diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ace8ab034..01c7deb7b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -42,6 +42,7 @@ declare_test(testresolvetype) declare_test(testreverseoperators) declare_test(testtemplates) declare_test(testtoposort) +declare_test(testvaluetypedefaultctortag) declare_test(testvoidarg) declare_test(testtyperevision) if (NOT DISABLE_DOCSTRINGS) diff --git a/tests/testvaluetypedefaultctortag.cpp b/tests/testvaluetypedefaultctortag.cpp new file mode 100644 index 000000000..e8f8d83ee --- /dev/null +++ b/tests/testvaluetypedefaultctortag.cpp @@ -0,0 +1,57 @@ +/* + * This file is part of the API Extractor project. + * + * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team <contact@pyside.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "testvaluetypedefaultctortag.h" +#include <QtTest/QTest> +#include "testutil.h" + +void TestValueTypeDefaultCtorTag::testValueTypeDefaultCtorTagArgument() +{ + const char* cppCode ="\ + struct A {\ + A(int,int);\ + };\ + struct B {};\ + "; + const char* xmlCode = "\ + <typesystem package='Foo'>\ + <primitive-type name='int' />\ + <value-type name='A' default-constructor='A(0, 0)' />\ + <value-type name='B' />\ + </typesystem>"; + TestUtil t(cppCode, xmlCode, false); + AbstractMetaClassList classes = t.builder()->classes(); + + AbstractMetaClass* classA = classes.findClass("A"); + QVERIFY(classA); + QVERIFY(classA->typeEntry()->hasDefaultConstructor()); + QCOMPARE(classA->typeEntry()->defaultConstructor(), QString("A(0, 0)")); + + AbstractMetaClass* classB = classes.findClass("B"); + QVERIFY(classB); + QVERIFY(!classB->typeEntry()->hasDefaultConstructor()); +} + +QTEST_APPLESS_MAIN(TestValueTypeDefaultCtorTag) + +#include "testvaluetypedefaultctortag.moc" diff --git a/tests/testvaluetypedefaultctortag.h b/tests/testvaluetypedefaultctortag.h new file mode 100644 index 000000000..a271d5f8f --- /dev/null +++ b/tests/testvaluetypedefaultctortag.h @@ -0,0 +1,36 @@ +/* +* This file is part of the API Extractor project. +* +* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#ifndef TESTVALUETYPEDEFAULTCTORTAG_H +#define TESTVALUETYPEDEFAULTCTORTAG_H + +#include <QObject> + +class TestValueTypeDefaultCtorTag : public QObject +{ + Q_OBJECT + private slots: + void testValueTypeDefaultCtorTagArgument(); +}; + +#endif diff --git a/typesystem.cpp b/typesystem.cpp index c54a12db2..66feacd59 100644 --- a/typesystem.cpp +++ b/typesystem.cpp @@ -431,8 +431,10 @@ bool Handler::startElement(const QString &, const QString &n, attributes["extensible"] = "no"; attributes["identified-by-value"] = QString(); break; - case StackElement::ObjectTypeEntry: case StackElement::ValueTypeEntry: + attributes["default-constructor"] = QString(); + // fall throooough + case StackElement::ObjectTypeEntry: attributes["force-abstract"] = QString("no"); attributes["deprecated"] = QString("no"); attributes["hash-function"] = QString(""); @@ -646,20 +648,25 @@ bool Handler::startElement(const QString &, const QString &n, element->entry = otype; } // fall through + case StackElement::ValueTypeEntry: { + if (!element->entry) { + ValueTypeEntry* typeEntry = new ValueTypeEntry(name, since); + QString defaultConstructor = attributes["default-constructor"]; + if (!defaultConstructor.isEmpty()) + typeEntry->setDefaultConstructor(defaultConstructor); + element->entry = typeEntry; + } + + // fall through case StackElement::NamespaceTypeEntry: if (!element->entry) element->entry = new NamespaceTypeEntry(name, since); - // fall through + // fall through case StackElement::ObjectTypeEntry: if (!element->entry) element->entry = new ObjectTypeEntry(name, since); - // fall through - case StackElement::ValueTypeEntry: { - if (!element->entry) - element->entry = new ValueTypeEntry(name, since); - element->entry->setStream(attributes["stream"] == QString("yes")); ComplexTypeEntry *ctype = static_cast<ComplexTypeEntry *>(element->entry); @@ -1745,6 +1752,26 @@ FieldModification ComplexTypeEntry::fieldModification(const QString &name) const return mod; } +// The things we do not to break the ABI... +typedef QHash<const ComplexTypeEntry*, QString> ComplexTypeEntryDefaultConstructorMap; +Q_GLOBAL_STATIC(ComplexTypeEntryDefaultConstructorMap, complexTypeEntryDefaultConstructors); + +void ComplexTypeEntry::setDefaultConstructor(const QString& defaultConstructor) +{ + if (!defaultConstructor.isEmpty()) + complexTypeEntryDefaultConstructors()->insert(this, defaultConstructor); +} +QString ComplexTypeEntry::defaultConstructor() const +{ + if (!complexTypeEntryDefaultConstructors()->contains(this)) + return QString(); + return complexTypeEntryDefaultConstructors()->value(this); +} +bool ComplexTypeEntry::hasDefaultConstructor() const +{ + return complexTypeEntryDefaultConstructors()->contains(this); +} + QString ContainerTypeEntry::targetLangPackage() const { return QString(); diff --git a/typesystem.h b/typesystem.h index bd99fd6c6..3fcb241fd 100644 --- a/typesystem.h +++ b/typesystem.h @@ -1439,6 +1439,7 @@ public: centry->setCodeSnips(codeSnips()); centry->setTargetLangPackage(targetLangPackage()); centry->setBaseContainerType(baseContainerType()); + centry->setDefaultConstructor(defaultConstructor()); return centry; } @@ -1629,6 +1630,9 @@ public: return m_baseContainerType; } + QString defaultConstructor() const; + void setDefaultConstructor(const QString& defaultConstructor); + bool hasDefaultConstructor() const; private: AddedFunctionList m_addedFunctions; |