aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--abstractmetabuilder.cpp24
-rw-r--r--abstractmetalang.cpp2
-rw-r--r--apiextractor.cpp7
-rw-r--r--apiextractor.h3
-rw-r--r--apiextractormacros.h15
-rw-r--r--tests/testabstractmetatype.cpp4
-rw-r--r--tests/testaddfunction.cpp2
-rw-r--r--tests/testcodeinjection.cpp4
-rw-r--r--tests/testenum.cpp2
-rw-r--r--tests/testmodifyfunction.cpp4
-rw-r--r--tests/testrefcounttag.cpp2
-rw-r--r--tests/testutil.h5
-rw-r--r--typedatabase.cpp51
-rw-r--r--typedatabase.h8
-rw-r--r--typesystem.cpp36
-rw-r--r--typesystem_p.h1
16 files changed, 110 insertions, 60 deletions
diff --git a/abstractmetabuilder.cpp b/abstractmetabuilder.cpp
index 29a21a05..f310aad4 100644
--- a/abstractmetabuilder.cpp
+++ b/abstractmetabuilder.cpp
@@ -72,7 +72,6 @@ void AbstractMetaBuilder::checkFunctionModifications()
TypeDatabase *types = TypeDatabase::instance();
SingleTypeEntryHash entryHash = types->entries();
QList<TypeEntry*> entries = entryHash.values();
- double apiVersion = TypeDatabase::instance()->apiVersion();
foreach (TypeEntry* entry, entries) {
if (!entry)
@@ -84,8 +83,6 @@ void AbstractMetaBuilder::checkFunctionModifications()
FunctionModificationList modifications = centry->functionModifications();
foreach (FunctionModification modification, modifications) {
- if (modification.version() > apiVersion)
- continue;
QString signature = modification.signature;
QString name = signature.trimmed();
@@ -423,11 +420,6 @@ bool AbstractMetaBuilder::build(QIODevice* input)
if (!funcEntry || !funcEntry->generateCode())
continue;
- if (!types->supportedApiVersion(funcEntry->version())) {
- m_rejectedFunctions.insert(func->name(), ApiIncompatible);
- continue;
- }
-
AbstractMetaFunction* metaFunc = traverseFunction(func);
if (!metaFunc)
continue;
@@ -486,11 +478,6 @@ bool AbstractMetaBuilder::build(QIODevice* input)
if (entry->isPrimitive())
continue;
- if (!types->supportedApiVersion(entry->version())) {
- m_rejectedClasses.insert(entry->name(), ApiIncompatible);
- continue;
- }
-
if ((entry->isValue() || entry->isObject())
&& !entry->isString()
&& !entry->isChar()
@@ -606,10 +593,6 @@ bool AbstractMetaBuilder::build(QIODevice* input)
// Functions added to the module on the type system.
foreach (AddedFunction addedFunc, types->globalUserFunctions()) {
- if (!types->supportedApiVersion(addedFunc.version())) {
- m_rejectedFunctions.insert(addedFunc.name(), ApiIncompatible);
- continue;
- }
AbstractMetaFunction* metaFunc = traverseFunction(addedFunc);
metaFunc->setFunctionType(AbstractMetaFunction::NormalFunction);
m_globalFunctions << metaFunc;
@@ -967,13 +950,6 @@ AbstractMetaEnum* AbstractMetaBuilder::traverseEnum(EnumModelItem enumItem, Abst
return 0;
}
- // Skipping api incompatible
- if (!TypeDatabase::instance()->supportedApiVersion(typeEntry->version())) {
- typeEntry->setCodeGeneration(TypeEntry::GenerateNothing);
- m_rejectedEnums.insert(qualifiedName, ApiIncompatible);
- return 0;
- }
-
AbstractMetaEnum* metaEnum = createMetaEnum();
if (enumsDeclarations.contains(qualifiedName)
|| enumsDeclarations.contains(enumName)) {
diff --git a/abstractmetalang.cpp b/abstractmetalang.cpp
index 5c1641c4..04fec2d8 100644
--- a/abstractmetalang.cpp
+++ b/abstractmetalang.cpp
@@ -814,7 +814,7 @@ CodeSnipList AbstractMetaFunction::injectedCodeSnips(CodeSnip::Position position
{
CodeSnipList result;
foreach (const FunctionModification mod, modifications(ownerClass())) {
- if (mod.isCodeInjection() && TypeDatabase::instance()->supportedApiVersion(mod.version())) {
+ if (mod.isCodeInjection()) {
QList<CodeSnip>::const_iterator it = mod.snips.constBegin();
for (;it != mod.snips.constEnd(); ++it) {
if ((it->language & language) && (it->position == position || position == CodeSnip::Any))
diff --git a/apiextractor.cpp b/apiextractor.cpp
index 6443c073..c26e6f69 100644
--- a/apiextractor.cpp
+++ b/apiextractor.cpp
@@ -106,7 +106,12 @@ void ApiExtractor::setSilent ( bool value )
void ApiExtractor::setApiVersion(double version)
{
- TypeDatabase::instance()->setApiVersion(version);
+ TypeDatabase::instance()->setApiVersion("*", QByteArray::number(version));
+}
+
+void ApiExtractor::setApiVersion(const QString& package, const QByteArray& version)
+{
+ TypeDatabase::instance()->setApiVersion(package, version);
}
void ApiExtractor::setDropTypeEntries(QString dropEntries)
diff --git a/apiextractor.h b/apiextractor.h
index 9874d127..0a71f1a2 100644
--- a/apiextractor.h
+++ b/apiextractor.h
@@ -48,7 +48,8 @@ public:
void addIncludePath(const QString& path);
void addIncludePath(const QStringList& paths);
void setLogDirectory(const QString& logDir);
- void setApiVersion(double version);
+ APIEXTRACTOR_DEPRECATED(void setApiVersion(double version));
+ void setApiVersion(const QString& package, const QByteArray& version);
void setDropTypeEntries(QString dropEntries);
AbstractMetaEnumList globalEnums() const;
diff --git a/apiextractormacros.h b/apiextractormacros.h
index 27a8778e..1c493c23 100644
--- a/apiextractormacros.h
+++ b/apiextractormacros.h
@@ -9,12 +9,15 @@
#else
#define APIEXTRACTOR_API
#endif
-#else
- #if __GNUC__ >= 4
- #define APIEXTRACTOR_API __attribute__ ((visibility("default")))
- #else
- #define APIEXTRACTOR_API
- #endif
+ #define APIEXTRACTOR_DEPRECATED(func) __declspec(deprecated) func
+#elif __GNUC__ >= 4
+ #define APIEXTRACTOR_API __attribute__ ((visibility("default")))
+ #define APIEXTRACTOR_DEPRECATED(func) func __attribute__ ((deprecated))
+#endif
+
+#ifndef APIEXTRACTOR_API
+ #define APIEXTRACTOR_API
+ #define APIEXTRACTOR_API(func) func
#endif
#endif
diff --git a/tests/testabstractmetatype.cpp b/tests/testabstractmetatype.cpp
index 207ec88f..17e5278a 100644
--- a/tests/testabstractmetatype.cpp
+++ b/tests/testabstractmetatype.cpp
@@ -64,7 +64,7 @@ void TestAbstractMetaType::testApiVersionSupported()
<function signature='justAtest2()' since='1.1'/>\
<function signature='justAtest3()'/>\
</typesystem>";
- TestUtil t(cppCode, xmlCode, false, 1.0);
+ TestUtil t(cppCode, xmlCode, false, "1.0");
AbstractMetaClassList classes = t.builder()->classes();
QCOMPARE(classes.size(), 2);
@@ -81,7 +81,7 @@ void TestAbstractMetaType::testApiVersionNotSupported()
const char* xmlCode = "<typesystem package='Foo'>\
<value-type name='object' since='0.1'/>\
</typesystem>";
- TestUtil t(cppCode, xmlCode, true, 0.1);
+ TestUtil t(cppCode, xmlCode, true, "0.1");
AbstractMetaClassList classes = t.builder()->classes();
QCOMPARE(classes.size(), 1);
diff --git a/tests/testaddfunction.cpp b/tests/testaddfunction.cpp
index 2d4ee91f..beb49fa1 100644
--- a/tests/testaddfunction.cpp
+++ b/tests/testaddfunction.cpp
@@ -347,7 +347,7 @@ void TestAddFunction::testAddFunctionWithApiVersion()
<inject-code class='target' position='beginning'>custom_code();</inject-code>\
</add-function>\
</typesystem>";
- TestUtil t(cppCode, xmlCode, true, 0.1);
+ TestUtil t(cppCode, xmlCode, true, "0.1");
AbstractMetaFunctionList globalFuncs = t.builder()->globalFunctions();
QCOMPARE(globalFuncs.count(), 1);
}
diff --git a/tests/testcodeinjection.cpp b/tests/testcodeinjection.cpp
index ab1aa803..ed2c379c 100644
--- a/tests/testcodeinjection.cpp
+++ b/tests/testcodeinjection.cpp
@@ -65,7 +65,7 @@ void TestCodeInjections::testInjectWithValidApiVersion()
</value-type>\
</typesystem>";
- TestUtil t(cppCode, xmlCode, true, 1.0);
+ TestUtil t(cppCode, xmlCode, true, "1.0");
AbstractMetaClassList classes = t.builder()->classes();
AbstractMetaClass* classA = classes.findClass("A");
@@ -84,7 +84,7 @@ void TestCodeInjections::testInjectWithInvalidApiVersion()
</value-type>\
</typesystem>";
- TestUtil t(cppCode, xmlCode, true, 0.1);
+ TestUtil t(cppCode, xmlCode, true, "0.1");
AbstractMetaClassList classes = t.builder()->classes();
AbstractMetaClass* classA = classes.findClass("A");
diff --git a/tests/testenum.cpp b/tests/testenum.cpp
index 62c43c6c..07aa0e8c 100644
--- a/tests/testenum.cpp
+++ b/tests/testenum.cpp
@@ -92,7 +92,7 @@ void TestEnum::testEnumWithApiVersion()
</value-type> \
</typesystem>";
- TestUtil t(cppCode, xmlCode, true, 0.1);
+ TestUtil t(cppCode, xmlCode, true, "0.1");
AbstractMetaClassList classes = t.builder()->classes();
QCOMPARE(classes.count(), 1);
QCOMPARE(classes[0]->enums().count(), 1);
diff --git a/tests/testmodifyfunction.cpp b/tests/testmodifyfunction.cpp
index 3f92e3e1..245a3e16 100644
--- a/tests/testmodifyfunction.cpp
+++ b/tests/testmodifyfunction.cpp
@@ -118,7 +118,7 @@ void TestModifyFunction::invalidateAfterUse()
</object-type>\
<object-type name='E' /> \
</typesystem>";
- TestUtil t(cppCode, xmlCode, false, 0.1);
+ TestUtil t(cppCode, xmlCode, false, "0.1");
AbstractMetaClassList classes = t.builder()->classes();
AbstractMetaClass* classB = classes.findClass("B");
const AbstractMetaFunction* func = classB->findFunction("call");
@@ -190,7 +190,7 @@ void TestModifyFunction::testWithApiVersion()
</modify-function>\
</object-type>\
</typesystem>";
- TestUtil t(cppCode, xmlCode, false, 0.1);
+ TestUtil t(cppCode, xmlCode, false, "0.1");
AbstractMetaClassList classes = t.builder()->classes();
AbstractMetaClass* classB = classes.findClass("B");
const AbstractMetaFunction* func = classB->findFunction("method");
diff --git a/tests/testrefcounttag.cpp b/tests/testrefcounttag.cpp
index 6f6f8736..424055f2 100644
--- a/tests/testrefcounttag.cpp
+++ b/tests/testrefcounttag.cpp
@@ -76,7 +76,7 @@ void TestRefCountTag::testWithApiVersion()
</object-type>\
</typesystem>";
- TestUtil t(cppCode, xmlCode, false, 0.1);
+ TestUtil t(cppCode, xmlCode, false, "0.1");
AbstractMetaClassList classes = t.builder()->classes();
AbstractMetaClass* classB = classes.findClass("B");
const AbstractMetaFunction* func = classB->findFunction("keepObject");
diff --git a/tests/testutil.h b/tests/testutil.h
index 775f3a1c..9519fb8b 100644
--- a/tests/testutil.h
+++ b/tests/testutil.h
@@ -32,14 +32,15 @@ class TestUtil
{
public:
TestUtil(const char* cppCode, const char* xmlCode,
- bool silent = true, double apiVersion = 0,
+ bool silent = true, const char* apiVersion = 0,
QStringList dropTypeEntries = QStringList())
: m_builder(0)
{
ReportHandler::setSilent(silent);
m_builder = new AbstractMetaBuilder;
TypeDatabase* td = TypeDatabase::instance(true);
- td->setApiVersion(apiVersion);
+ if (apiVersion)
+ td->setApiVersion("*", apiVersion);
td->setDropTypeEntries(dropTypeEntries);
QBuffer buffer;
// parse typesystem
diff --git a/typedatabase.cpp b/typedatabase.cpp
index 4ff2128e..d5c1eb6c 100644
--- a/typedatabase.cpp
+++ b/typedatabase.cpp
@@ -31,6 +31,11 @@
// #include <tr1/tuple>
#include <algorithm>
+// package -> api-version
+typedef QMap<QString, QByteArray> ApiVersionMap;
+
+Q_GLOBAL_STATIC(ApiVersionMap, apiVersions)
+
TypeDatabase::TypeDatabase() : m_suppressWarnings(true), m_apiVersion(0)
{
addType(new VoidTypeEntry());
@@ -349,6 +354,9 @@ bool TypeDatabase::parseFile(const QString &filename, bool generate)
bool TypeDatabase::parseFile(QIODevice* device, bool generate)
{
+ if (m_apiVersion) // backwards compatibility with deprecated API
+ setApiVersion("*", QByteArray::number(m_apiVersion));
+
QXmlInputSource source(device);
QXmlSimpleReader reader;
Handler handler(this, generate);
@@ -495,3 +503,46 @@ int getMaxTypeIndex()
return maxTypeIndex;
}
+void TypeDatabase::setApiVersion(const QString& package, const QByteArray& version)
+{
+ (*apiVersions())[package.trimmed()] = version.trimmed();
+}
+
+/**
+ * Returns -1, 0 or 1 if v1 is less, equal or greater than v2
+ */
+static int versionCheck(const QByteArray& v1, const QByteArray& v2)
+{
+ if (v1.isEmpty() || v2.isEmpty())
+ return 0;
+
+ QList<QByteArray> v1Components = v1.split('.');
+ QList<QByteArray> v2Components = v2.split('.');
+ int numComponents = qMax(v1Components.count(), v2Components.count());
+ while (v1Components.count() < numComponents)
+ v1Components.append("0");
+ while (v2Components.count() < numComponents)
+ v2Components.append("0");
+
+ for (int i = 0, max = v1Components.count(); i < max; ++i) {
+ int v1Comp = v1Components[i].toInt();
+ int v2Comp = v2Components[i].toInt();
+ if (v1Comp > v2Comp)
+ return 1;
+ else if (v1Comp < v2Comp)
+ return -1;
+ }
+ return 0;
+}
+
+bool TypeDatabase::checkApiVersion(const QString& package, const QByteArray& version) const
+{
+ ApiVersionMap* vMap = apiVersions();
+ ApiVersionMap::const_iterator it = vMap->begin();
+ for (; it != vMap->end(); ++it) {
+ QRegExp regex(it.key(), Qt::CaseSensitive, QRegExp::Wildcard);
+ if (regex.exactMatch(package))
+ return versionCheck(it.value(), version) >= 0;
+ }
+ return false;
+}
diff --git a/typedatabase.h b/typedatabase.h
index ef454ff0..8c735c1c 100644
--- a/typedatabase.h
+++ b/typedatabase.h
@@ -173,17 +173,19 @@ public:
bool parseFile(const QString &filename, bool generate = true);
bool parseFile(QIODevice* device, bool generate = true);
- double apiVersion() const
+ APIEXTRACTOR_DEPRECATED(double apiVersion() const)
{
return m_apiVersion;
}
- void setApiVersion(double version)
+ APIEXTRACTOR_DEPRECATED(void setApiVersion(double version))
{
m_apiVersion = version;
}
+ void setApiVersion(const QString& package, const QByteArray& version);
- bool supportedApiVersion(double version) const;
+ APIEXTRACTOR_DEPRECATED(bool supportedApiVersion(double version) const);
+ bool checkApiVersion(const QString& package, const QByteArray& version) const;
const QStringList& dropTypeEntries() const
{
diff --git a/typesystem.cpp b/typesystem.cpp
index d062655d..0c1eae7c 100644
--- a/typesystem.cpp
+++ b/typesystem.cpp
@@ -40,6 +40,7 @@ Handler::Handler(TypeDatabase* database, bool generate)
m_current = 0;
m_currentDroppedEntry = 0;
m_currentDroppedEntryDepth = 0;
+ m_ignoreDepth = 0;
tagNames["rejection"] = StackElement::Rejection;
tagNames["primitive-type"] = StackElement::PrimitiveTypeEntry;
@@ -125,6 +126,11 @@ void Handler::fetchAttributeValues(const QString &name, const QXmlAttributes &at
bool Handler::endElement(const QString &, const QString &localName, const QString &)
{
+ if (m_ignoreDepth) {
+ --m_ignoreDepth;
+ return true;
+ }
+
if (m_currentDroppedEntry) {
if (m_currentDroppedEntryDepth == 1) {
m_current = m_currentDroppedEntry->parent;
@@ -222,7 +228,7 @@ bool Handler::endElement(const QString &, const QString &localName, const QStrin
bool Handler::characters(const QString &ch)
{
- if (m_currentDroppedEntry)
+ if (m_currentDroppedEntry || m_ignoreDepth)
return true;
if (m_current->type == StackElement::Template) {
@@ -380,6 +386,20 @@ static QString getNamePrefix(StackElement* element)
bool Handler::startElement(const QString &, const QString &n,
const QString &, const QXmlAttributes &atts)
{
+ if (m_ignoreDepth) {
+ ++m_ignoreDepth;
+ return true;
+ }
+
+ if (!m_defaultPackage.isEmpty() && atts.index("since") != -1) {
+ TypeDatabase* td = TypeDatabase::instance();
+ if (!td->checkApiVersion(m_defaultPackage, atts.value("since").toAscii())) {
+ ++m_ignoreDepth;
+ return true;
+ }
+ }
+
+
QString tagName = n.toLower();
if (tagName == "import-file")
return importFileElement(atts);
@@ -1016,10 +1036,6 @@ bool Handler::startElement(const QString &, const QString &n,
return false;
}
QString name = attributes["name"];
-
- if (!name.isEmpty() && m_database->supportedApiVersion(since))
- m_currentEnum->addEnumValueRejection(name);
-
} break;
case StackElement::ReplaceType: {
if (topElement.type != StackElement::ModifyArgument) {
@@ -1711,13 +1727,7 @@ PrimitiveTypeEntry* PrimitiveTypeEntry::basicAliasedTypeEntry() const
CodeSnipList TypeEntry::codeSnips() const
{
- CodeSnipList lst;
- TypeDatabase *td = TypeDatabase::instance();
- foreach(CodeSnip cs, m_codeSnips) {
- if (td->supportedApiVersion(cs.version))
- lst.append(cs);
- }
- return lst;
+ return m_codeSnips;
}
QString Modification::accessModifierString() const
@@ -1735,7 +1745,7 @@ FunctionModificationList ComplexTypeEntry::functionModifications(const QString &
TypeDatabase *td = TypeDatabase::instance();
for (int i = 0; i < m_functionMods.count(); ++i) {
const FunctionModification &mod = m_functionMods.at(i);
- if ((mod.signature == signature) && (td->supportedApiVersion(mod.version())))
+ if (mod.signature == signature)
lst << mod;
}
diff --git a/typesystem_p.h b/typesystem_p.h
index d69de3fc..0cf57550 100644
--- a/typesystem_p.h
+++ b/typesystem_p.h
@@ -151,6 +151,7 @@ private:
StackElement* m_current;
StackElement* m_currentDroppedEntry;
int m_currentDroppedEntryDepth;
+ int m_ignoreDepth;
QString m_defaultPackage;
QString m_defaultSuperclass;
QString m_error;