aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/ApiExtractor/typesystemparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/ApiExtractor/typesystemparser.cpp')
-rw-r--r--sources/shiboken2/ApiExtractor/typesystemparser.cpp595
1 files changed, 378 insertions, 217 deletions
diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.cpp b/sources/shiboken2/ApiExtractor/typesystemparser.cpp
index 5440de5c0..d2648d0b4 100644
--- a/sources/shiboken2/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystemparser.cpp
@@ -56,23 +56,28 @@ static inline QString quoteBeforeLineAttribute() { return QStringLiteral("quote-
static inline QString textAttribute() { return QStringLiteral("text"); }
static inline QString nameAttribute() { return QStringLiteral("name"); }
static inline QString sinceAttribute() { return QStringLiteral("since"); }
+static inline QString untilAttribute() { return QStringLiteral("until"); }
static inline QString defaultSuperclassAttribute() { return QStringLiteral("default-superclass"); }
static inline QString deleteInMainThreadAttribute() { return QStringLiteral("delete-in-main-thread"); }
static inline QString deprecatedAttribute() { return QStringLiteral("deprecated"); }
static inline QString exceptionHandlingAttribute() { return QStringLiteral("exception-handling"); }
static inline QString extensibleAttribute() { return QStringLiteral("extensible"); }
+static inline QString fileNameAttribute() { return QStringLiteral("file-name"); }
static inline QString flagsAttribute() { return QStringLiteral("flags"); }
static inline QString forceAbstractAttribute() { return QStringLiteral("force-abstract"); }
static inline QString forceIntegerAttribute() { return QStringLiteral("force-integer"); }
static inline QString formatAttribute() { return QStringLiteral("format"); }
+static inline QString generateUsingAttribute() { return QStringLiteral("generate-using"); }
static inline QString classAttribute() { return QStringLiteral("class"); }
static inline QString generateAttribute() { return QStringLiteral("generate"); }
+static inline QString generateGetSetDefAttribute() { return QStringLiteral("generate-getsetdef"); }
static inline QString genericClassAttribute() { return QStringLiteral("generic-class"); }
static inline QString indexAttribute() { return QStringLiteral("index"); }
static inline QString invalidateAfterUseAttribute() { return QStringLiteral("invalidate-after-use"); }
static inline QString locationAttribute() { return QStringLiteral("location"); }
static inline QString modifiedTypeAttribute() { return QStringLiteral("modified-type"); }
static inline QString modifierAttribute() { return QStringLiteral("modifier"); }
+static inline QString overloadNumberAttribute() { return QStringLiteral("overload-number"); }
static inline QString ownershipAttribute() { return QStringLiteral("owner"); }
static inline QString packageAttribute() { return QStringLiteral("package"); }
static inline QString positionAttribute() { return QStringLiteral("position"); }
@@ -81,6 +86,7 @@ static inline QString preferredTargetLangTypeAttribute() { return QStringLiteral
static inline QString removeAttribute() { return QStringLiteral("remove"); }
static inline QString renameAttribute() { return QStringLiteral("rename"); }
static inline QString readAttribute() { return QStringLiteral("read"); }
+static inline QString targetLangNameAttribute() { return QStringLiteral("target-lang-name"); }
static inline QString writeAttribute() { return QStringLiteral("write"); }
static inline QString replaceAttribute() { return QStringLiteral("replace"); }
static inline QString toAttribute() { return QStringLiteral("to"); }
@@ -92,6 +98,7 @@ static inline QString sourceAttribute() { return QStringLiteral("source"); }
static inline QString streamAttribute() { return QStringLiteral("stream"); }
static inline QString xPathAttribute() { return QStringLiteral("xpath"); }
static inline QString virtualSlotAttribute() { return QStringLiteral("virtual-slot"); }
+static inline QString visibleAttribute() { return QStringLiteral("visible"); }
static inline QString enumIdentifiedByValueAttribute() { return QStringLiteral("identified-by-value"); }
static inline QString noAttributeValue() { return QStringLiteral("no"); }
@@ -145,7 +152,7 @@ static QString extractSnippet(const QString &code, const QString &snippetLabel)
} else if (useLine)
result += line.toString() + QLatin1Char('\n');
}
- return result;
+ return CodeSnipAbstract::fixSpaces(result);
}
template <class EnumType, Qt::CaseSensitivity cs = Qt::CaseInsensitive>
@@ -203,13 +210,8 @@ ENUM_LOOKUP_BEGIN(TypeSystem::Language, Qt::CaseInsensitive,
languageFromAttribute, TypeSystem::NoLanguage)
{
{u"all", TypeSystem::All}, // sorted!
- {u"constructors", TypeSystem::Constructors},
- {u"destructor-function", TypeSystem::DestructorFunction},
- {u"interface", TypeSystem::Interface},
- {u"library-initializer", TypeSystem::PackageInitializer},
{u"native", TypeSystem::NativeCode}, // em algum lugar do cpp
{u"shell", TypeSystem::ShellCode}, // coloca no header, mas antes da declaracao da classe
- {u"shell-declaration", TypeSystem::ShellDeclaration},
{u"target", TypeSystem::TargetLangCode} // em algum lugar do cpp
};
ENUM_LOOKUP_BINARY_SEARCH()
@@ -268,10 +270,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::CodeSnipPosition, Qt::CaseInsensitive,
{
{u"beginning", TypeSystem::CodeSnipPositionBeginning},
{u"end", TypeSystem::CodeSnipPositionEnd},
- {u"declaration", TypeSystem::CodeSnipPositionDeclaration},
- {u"prototype-initialization", TypeSystem::CodeSnipPositionPrototypeInitialization},
- {u"constructor-initialization", TypeSystem::CodeSnipPositionConstructorInitialization},
- {u"constructor", TypeSystem::CodeSnipPositionConstructor}
+ {u"declaration", TypeSystem::CodeSnipPositionDeclaration}
};
ENUM_LOOKUP_LINEAR_SEARCH()
@@ -293,7 +292,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::DocModificationMode, Qt::CaseInsensitive,
};
ENUM_LOOKUP_LINEAR_SEARCH()
-ENUM_LOOKUP_BEGIN(ContainerTypeEntry::Type, Qt::CaseSensitive,
+ENUM_LOOKUP_BEGIN(ContainerTypeEntry::ContainerKind, Qt::CaseSensitive,
containerTypeFromAttribute, ContainerTypeEntry::NoContainer)
{
{u"list", ContainerTypeEntry::ListContainer},
@@ -368,6 +367,7 @@ ENUM_LOOKUP_BEGIN(StackElement::ElementType, Qt::CaseInsensitive,
{u"object-type", StackElement::ObjectTypeEntry},
{u"parent", StackElement::ParentOwner},
{u"primitive-type", StackElement::PrimitiveTypeEntry},
+ {u"property", StackElement::Property},
{u"reference-count", StackElement::ReferenceCount},
{u"reject-enum-value", StackElement::RejectEnumValue},
{u"rejection", StackElement::Rejection},
@@ -380,6 +380,7 @@ ENUM_LOOKUP_BEGIN(StackElement::ElementType, Qt::CaseInsensitive,
{u"replace-type", StackElement::ReplaceType},
{u"smart-pointer-type", StackElement::SmartPointerTypeEntry},
{u"suppress-warning", StackElement::SuppressedWarning},
+ {u"system-include", StackElement::SystemInclude},
{u"target-to-native", StackElement::TargetToNative},
{u"template", StackElement::Template},
{u"typedef-type", StackElement::TypedefTypeEntry},
@@ -388,6 +389,17 @@ ENUM_LOOKUP_BEGIN(StackElement::ElementType, Qt::CaseInsensitive,
};
ENUM_LOOKUP_BINARY_SEARCH()
+ENUM_LOOKUP_BEGIN(TypeSystem::Visibility, Qt::CaseSensitive,
+ visibilityFromAttribute, TypeSystem::Visibility::Unspecified)
+{
+ {u"no", TypeSystem::Visibility::Invisible},
+ {u"false", TypeSystem::Visibility::Invisible},
+ {u"auto", TypeSystem::Visibility::Auto},
+ {u"yes", TypeSystem::Visibility::Visible},
+ {u"true", TypeSystem::Visibility::Visible},
+};
+ENUM_LOOKUP_LINEAR_SEARCH()
+
static int indexOfAttribute(const QXmlStreamAttributes &atts,
QStringView name)
{
@@ -493,7 +505,7 @@ QString TypeSystemEntityResolver::resolveUndeclaredEntity(const QString &name)
TypeSystemParser::TypeSystemParser(TypeDatabase *database, bool generate) :
m_database(database),
- m_generate(generate ? TypeEntry::GenerateAll : TypeEntry::GenerateForSubclass)
+ m_generate(generate ? TypeEntry::GenerateCode : TypeEntry::GenerateForSubclass)
{
}
@@ -511,14 +523,14 @@ static QString msgReaderMessage(const QXmlStreamReader &reader,
{
QString message;
QTextStream str(&message);
- str << type << ": ";
const QString fileName = readerFileName(reader);
if (fileName.isEmpty())
str << "<stdin>:";
else
str << QDir::toNativeSeparators(fileName) << ':';
+ // Use a tab separator like SourceLocation for suppression detection
str << reader.lineNumber() << ':' << reader.columnNumber()
- << ": " << what;
+ << ":\t" << type << ": " << what;
return message;
}
@@ -573,17 +585,6 @@ static inline
attribute.value());
}
-static QString msgInvalidVersion(const QStringRef &version, const QString &package = QString())
-{
- QString result;
- QTextStream str(&result);
- str << "Invalid version \"" << version << '"';
- if (!package.isEmpty())
- str << "\" specified for package " << package;
- str << '.';
- return result;
-}
-
static bool addRejection(TypeDatabase *database, QXmlStreamAttributes *attributes,
QString *errorMessage)
{
@@ -634,9 +635,21 @@ bool TypeSystemParser::parse(QXmlStreamReader &reader)
{
m_error.clear();
m_currentPath.clear();
+ m_currentFile.clear();
+ m_smartPointerInstantiations.clear();
+ const bool result = parseXml(reader) && setupSmartPointerInstantiations();
+ m_smartPointerInstantiations.clear();
+ return result;
+}
+
+bool TypeSystemParser::parseXml(QXmlStreamReader &reader)
+{
const QString fileName = readerFileName(reader);
- if (!fileName.isEmpty())
- m_currentPath = QFileInfo(fileName).absolutePath();
+ if (!fileName.isEmpty()) {
+ QFileInfo fi(fileName);
+ m_currentPath = fi.absolutePath();
+ m_currentFile = fi.absoluteFilePath();
+ }
m_entityResolver.reset(new TypeSystemEntityResolver(m_currentPath));
reader.setEntityResolver(m_entityResolver.data());
@@ -677,6 +690,62 @@ bool TypeSystemParser::parse(QXmlStreamReader &reader)
return true;
}
+// Split a type list potentially with template types
+// "A<B,C>,D" -> ("A<B,C>", "D")
+static QStringList splitTypeList(const QString &s)
+{
+ QStringList result;
+ int templateDepth = 0;
+ int lastPos = 0;
+ const int size = s.size();
+ for (int i = 0; i < size; ++i) {
+ switch (s.at(i).toLatin1()) {
+ case '<':
+ ++templateDepth;
+ break;
+ case '>':
+ --templateDepth;
+ break;
+ case ',':
+ if (templateDepth == 0) {
+ result.append(s.mid(lastPos, i - lastPos).trimmed());
+ lastPos = i + 1;
+ }
+ break;
+ }
+ }
+ if (lastPos < size)
+ result.append(s.mid(lastPos, size - lastPos).trimmed());
+ return result;
+}
+
+bool TypeSystemParser::setupSmartPointerInstantiations()
+{
+ for (auto it = m_smartPointerInstantiations.cbegin(),
+ end = m_smartPointerInstantiations.cend(); it != end; ++it) {
+ auto smartPointerEntry = it.key();
+ const auto instantiationNames = splitTypeList(it.value());
+ SmartPointerTypeEntry::Instantiations instantiations;
+ instantiations.reserve(instantiationNames.size());
+ for (const auto &instantiationName : instantiationNames) {
+ const auto types = m_database->findCppTypes(instantiationName);
+ if (types.isEmpty()) {
+ m_error =
+ msgCannotFindTypeEntryForSmartPointer(instantiationName,
+ smartPointerEntry->name());
+ return false;
+ }
+ if (types.size() > 1) {
+ m_error = msgAmbiguousTypesFound(instantiationName, types);
+ return false;
+ }
+ instantiations.append(types.constFirst());
+ }
+ smartPointerEntry->setInstantiations(instantiations);
+ }
+ return true;
+}
+
bool TypeSystemParser::endElement(const QStringRef &localName)
{
if (m_ignoreDepth) {
@@ -704,7 +773,7 @@ bool TypeSystemParser::endElement(const QStringRef &localName)
switch (m_current->type) {
case StackElement::Root:
- if (m_generate == TypeEntry::GenerateAll) {
+ if (m_generate == TypeEntry::GenerateCode) {
TypeDatabase::instance()->addGlobalUserFunctions(m_contextStack.top()->addedFunctions);
TypeDatabase::instance()->addGlobalUserFunctionModifications(m_contextStack.top()->functionMods);
for (CustomConversion *customConversion : qAsConst(customConversionsForReview)) {
@@ -719,18 +788,26 @@ bool TypeSystemParser::endElement(const QStringRef &localName)
case StackElement::InterfaceTypeEntry:
case StackElement::NamespaceTypeEntry: {
auto *centry = static_cast<ComplexTypeEntry *>(m_current->entry);
- centry->setAddedFunctions(m_contextStack.top()->addedFunctions);
- centry->setFunctionModifications(m_contextStack.top()->functionMods);
- centry->setFieldModifications(m_contextStack.top()->fieldMods);
- centry->setCodeSnips(m_contextStack.top()->codeSnips);
- centry->setDocModification(m_contextStack.top()->docModifications);
-
- if (centry->designatedInterface()) {
- centry->designatedInterface()->setCodeSnips(m_contextStack.top()->codeSnips);
- centry->designatedInterface()->setFunctionModifications(m_contextStack.top()->functionMods);
- }
+ auto top = m_contextStack.top();
+ centry->setAddedFunctions(top->addedFunctions);
+ centry->setFunctionModifications(top->functionMods);
+ centry->setFieldModifications(top->fieldMods);
+ centry->setCodeSnips(top->codeSnips);
+ centry->setDocModification(top->docModifications);
}
break;
+
+ case StackElement::TypedefTypeEntry: {
+ auto *centry = static_cast<TypedefEntry *>(m_current->entry)->target();
+ auto top = m_contextStack.top();
+ centry->setAddedFunctions(centry->addedFunctions() + top->addedFunctions);
+ centry->setFunctionModifications(centry->functionModifications() + top->functionMods);
+ centry->setFieldModifications(centry->fieldModifications() + top->fieldMods);
+ centry->setCodeSnips(centry->codeSnips() + top->codeSnips);
+ centry->setDocModification(centry->docModifications() + top->docModifications);
+ }
+ break;
+
case StackElement::AddFunction: {
// Leaving add-function: Assign all modifications to the added function
StackElementContext *top = m_contextStack.top();
@@ -811,7 +888,7 @@ bool TypeSystemParser::endElement(const QStringRef &localName)
break;
default:
break; // nada
- };
+ }
break;
default:
break;
@@ -887,7 +964,7 @@ bool TypeSystemParser::characters(const String &ch)
break;
default:
Q_ASSERT(false);
- };
+ }
return true;
}
}
@@ -958,7 +1035,6 @@ bool TypeSystemParser::importFileElement(const QXmlStreamAttributes &atts)
static bool convertBoolean(QStringView value, const QString &attributeName, bool defaultValue)
{
-#ifdef QTBUG_69389_FIXED
if (value.compare(trueAttributeValue(), Qt::CaseInsensitive) == 0
|| value.compare(yesAttributeValue(), Qt::CaseInsensitive) == 0) {
return true;
@@ -967,16 +1043,6 @@ static bool convertBoolean(QStringView value, const QString &attributeName, bool
|| value.compare(noAttributeValue(), Qt::CaseInsensitive) == 0) {
return false;
}
-#else
- if (QtPrivate::compareStrings(value, trueAttributeValue(), Qt::CaseInsensitive) == 0
- || QtPrivate::compareStrings(value, yesAttributeValue(), Qt::CaseInsensitive) == 0) {
- return true;
- }
- if (QtPrivate::compareStrings(value, falseAttributeValue(), Qt::CaseInsensitive) == 0
- || QtPrivate::compareStrings(value, noAttributeValue(), Qt::CaseInsensitive) == 0) {
- return false;
- }
-#endif
const QString warn = QStringLiteral("Boolean value '%1' not supported in attribute '%2'. Use 'yes' or 'no'. Defaulting to '%3'.")
.arg(value)
.arg(attributeName,
@@ -1010,19 +1076,23 @@ static bool convertRemovalAttribute(QStringView remove, Modification& mod, QStri
return false;
}
-static void getNamePrefixRecursive(StackElement* element, QStringList& names)
-{
- if (!element->parent || !element->parent->entry)
- return;
- getNamePrefixRecursive(element->parent, names);
- names << element->parent->entry->name();
-}
-
-static QString getNamePrefix(StackElement* element)
+// Check whether an entry should be dropped, allowing for dropping the module
+// name (match 'Class' and 'Module.Class').
+static bool shouldDropTypeEntry(const TypeDatabase *db,
+ const StackElement *element,
+ QString name)
{
- QStringList names;
- getNamePrefixRecursive(element, names);
- return names.join(QLatin1Char('.'));
+ for (auto e = element->parent; e ; e = e->parent) {
+ if (e->entry) {
+ if (e->entry->type() == TypeEntry::TypeSystemType) {
+ if (db->shouldDropTypeEntry(name)) // Unqualified
+ return true;
+ }
+ name.prepend(QLatin1Char('.'));
+ name.prepend(e->entry->name());
+ }
+ }
+ return db->shouldDropTypeEntry(name);
}
// Returns empty string if there's no error.
@@ -1040,8 +1110,24 @@ static QString checkSignatureError(const QString& signature, const QString& tag)
return QString();
}
-void TypeSystemParser::applyCommonAttributes(TypeEntry *type, QXmlStreamAttributes *attributes) const
+inline const TypeEntry *TypeSystemParser::currentParentTypeEntry() const
+{
+ return m_current ? m_current->entry : nullptr;
+}
+
+bool TypeSystemParser::checkRootElement()
{
+ const bool ok = currentParentTypeEntry() != nullptr;
+ if (!ok)
+ m_error = msgNoRootTypeSystemEntry();
+ return ok;
+}
+
+void TypeSystemParser::applyCommonAttributes(const QXmlStreamReader &reader, TypeEntry *type,
+ QXmlStreamAttributes *attributes) const
+{
+ type->setSourceLocation(SourceLocation(m_currentFile,
+ reader.lineNumber()));
type->setCodeGeneration(m_generate);
const int revisionIndex =
indexOfAttribute(*attributes, u"revision");
@@ -1050,31 +1136,36 @@ void TypeSystemParser::applyCommonAttributes(TypeEntry *type, QXmlStreamAttribut
}
FlagsTypeEntry *
- TypeSystemParser::parseFlagsEntry(const QXmlStreamReader &,
- EnumTypeEntry *enumEntry,
- const QString &name, QString flagName,
+ TypeSystemParser::parseFlagsEntry(const QXmlStreamReader &reader,
+ EnumTypeEntry *enumEntry, QString flagName,
const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
- FlagsTypeEntry *ftype = new FlagsTypeEntry(QLatin1String("QFlags<") + name + QLatin1Char('>'), since);
+ if (!checkRootElement())
+ return nullptr;
+ auto ftype = new FlagsTypeEntry(QLatin1String("QFlags<") + enumEntry->name() + QLatin1Char('>'),
+ since,
+ currentParentTypeEntry()->typeSystemTypeEntry());
ftype->setOriginator(enumEntry);
ftype->setTargetLangPackage(enumEntry->targetLangPackage());
- // Try to get the guess the qualified flag name
- const int lastSepPos = name.lastIndexOf(colonColon());
- if (lastSepPos >= 0 && !flagName.contains(colonColon()))
- flagName.prepend(name.left(lastSepPos + 2));
+ // Try toenumEntry get the guess the qualified flag name
+ if (!flagName.contains(colonColon())) {
+ auto eq = enumEntry->qualifier();
+ if (!eq.isEmpty())
+ flagName.prepend(eq + colonColon());
+ }
ftype->setOriginalName(flagName);
- applyCommonAttributes(ftype, attributes);
- QString n = ftype->originalName();
+ applyCommonAttributes(reader, ftype, attributes);
- QStringList lst = n.split(colonColon());
+ QStringList lst = flagName.split(colonColon());
+ const QString targetLangFlagName = QStringList(lst.mid(0, lst.size() - 1)).join(QLatin1Char('.'));
const QString &targetLangQualifier = enumEntry->targetLangQualifier();
- if (QStringList(lst.mid(0, lst.size() - 1)).join(colonColon()) != targetLangQualifier) {
+ if (targetLangFlagName != targetLangQualifier) {
qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("enum %1 and flags %2 differ in qualifiers")
- .arg(targetLangQualifier, lst.constFirst());
+ << QStringLiteral("enum %1 and flags %2 (%3) differ in qualifiers")
+ .arg(targetLangQualifier, lst.constFirst(), targetLangFlagName);
}
ftype->setFlagsName(lst.constLast());
@@ -1092,13 +1183,16 @@ FlagsTypeEntry *
}
SmartPointerTypeEntry *
- TypeSystemParser::parseSmartPointerEntry(const QXmlStreamReader &,
+ TypeSystemParser::parseSmartPointerEntry(const QXmlStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
+ if (!checkRootElement())
+ return nullptr;
QString smartPointerType;
QString getter;
QString refCountMethodName;
+ QString instantiations;
for (int i = attributes->size() - 1; i >= 0; --i) {
const QStringRef name = attributes->at(i).qualifiedName();
if (name == QLatin1String("type")) {
@@ -1107,6 +1201,8 @@ SmartPointerTypeEntry *
getter = attributes->takeAt(i).value().toString();
} else if (name == QLatin1String("ref-count-method")) {
refCountMethodName = attributes->takeAt(i).value().toString();
+ } else if (name == QLatin1String("instantiations")) {
+ instantiations = attributes->takeAt(i).value().toString();
}
}
@@ -1138,8 +1234,10 @@ SmartPointerTypeEntry *
return nullptr;
}
- auto *type = new SmartPointerTypeEntry(name, getter, smartPointerType, refCountMethodName, since);
- applyCommonAttributes(type, attributes);
+ auto *type = new SmartPointerTypeEntry(name, getter, smartPointerType,
+ refCountMethodName, since, currentParentTypeEntry());
+ applyCommonAttributes(reader, type, attributes);
+ m_smartPointerInstantiations.insert(type, instantiations);
return type;
}
@@ -1148,12 +1246,14 @@ PrimitiveTypeEntry *
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
- auto *type = new PrimitiveTypeEntry(name, since);
- applyCommonAttributes(type, attributes);
+ if (!checkRootElement())
+ return nullptr;
+ auto *type = new PrimitiveTypeEntry(name, since, currentParentTypeEntry());
+ applyCommonAttributes(reader, type, attributes);
for (int i = attributes->size() - 1; i >= 0; --i) {
const QStringRef name = attributes->at(i).qualifiedName();
- if (name == QLatin1String("target-lang-name")) {
- type->setTargetLangName(attributes->takeAt(i).value().toString());
+ if (name == targetLangNameAttribute()) {
+ type->setTargetLangName(attributes->takeAt(i).value().toString());
} else if (name == QLatin1String("target-lang-api-name")) {
type->setTargetLangApiName(attributes->takeAt(i).value().toString());
} else if (name == preferredConversionAttribute()) {
@@ -1168,8 +1268,6 @@ PrimitiveTypeEntry *
}
}
- if (type->targetLangName().isEmpty())
- type->setTargetLangName(type->name());
if (type->targetLangApiName().isEmpty())
type->setTargetLangApiName(type->name());
type->setTargetLangPackage(m_defaultPackage);
@@ -1177,40 +1275,37 @@ PrimitiveTypeEntry *
}
ContainerTypeEntry *
- TypeSystemParser::parseContainerTypeEntry(const QXmlStreamReader &,
+ TypeSystemParser::parseContainerTypeEntry(const QXmlStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
+ if (!checkRootElement())
+ return nullptr;
const int typeIndex = indexOfAttribute(*attributes, u"type");
if (typeIndex == -1) {
m_error = QLatin1String("no 'type' attribute specified");
return nullptr;
}
const QStringRef typeName = attributes->takeAt(typeIndex).value();
- ContainerTypeEntry::Type containerType = containerTypeFromAttribute(typeName);
+ ContainerTypeEntry::ContainerKind containerType = containerTypeFromAttribute(typeName);
if (containerType == ContainerTypeEntry::NoContainer) {
m_error = QLatin1String("there is no container of type ") + typeName.toString();
return nullptr;
}
- auto *type = new ContainerTypeEntry(name, containerType, since);
- applyCommonAttributes(type, attributes);
+ auto *type = new ContainerTypeEntry(name, containerType, since, currentParentTypeEntry());
+ applyCommonAttributes(reader, type, attributes);
return type;
}
EnumTypeEntry *
TypeSystemParser::parseEnumTypeEntry(const QXmlStreamReader &reader,
- const QString &fullName, const QVersionNumber &since,
+ const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
- QString scope;
- QString name = fullName;
- const int sep = fullName.lastIndexOf(colonColon());
- if (sep != -1) {
- scope = fullName.left(sep);
- name = fullName.right(fullName.size() - sep - 2);
- }
- auto *entry = new EnumTypeEntry(scope, name, since);
- applyCommonAttributes(entry, attributes);
+ if (!checkRootElement())
+ return nullptr;
+ auto *entry = new EnumTypeEntry(name, since, currentParentTypeEntry());
+ applyCommonAttributes(reader, entry, attributes);
entry->setTargetLangPackage(m_defaultPackage);
QString flagNames;
@@ -1237,51 +1332,22 @@ EnumTypeEntry *
if (!flagNames.isEmpty()) {
const QStringList &flagNameList = flagNames.split(QLatin1Char(','));
for (const QString &flagName : flagNameList)
- parseFlagsEntry(reader, entry, fullName, flagName.trimmed(), since, attributes);
+ parseFlagsEntry(reader, entry, flagName.trimmed(), since, attributes);
}
return entry;
}
-ObjectTypeEntry *
- TypeSystemParser::parseInterfaceTypeEntry(const QXmlStreamReader &,
- const QString &name, const QVersionNumber &since,
- QXmlStreamAttributes *attributes)
-{
- auto *otype = new ObjectTypeEntry(name, since);
- applyCommonAttributes(otype, attributes);
- QString targetLangName = name;
- bool generate = true;
- for (int i = attributes->size() - 1; i >= 0; --i) {
- const QStringRef name = attributes->at(i).qualifiedName();
- if (name == QLatin1String("target-lang-name")) {
- targetLangName = attributes->takeAt(i).value().toString();
- } else if (name == generateAttribute()) {
- generate = convertBoolean(attributes->takeAt(i).value(),
- generateAttribute(), true);
- }
- }
-
- InterfaceTypeEntry *itype =
- new InterfaceTypeEntry(InterfaceTypeEntry::interfaceName(targetLangName), since);
-
- if (generate)
- itype->setCodeGeneration(m_generate);
- else
- itype->setCodeGeneration(TypeEntry::GenerateForSubclass);
-
- otype->setDesignatedInterface(itype);
- itype->setOrigin(otype);
- return otype;
-}
NamespaceTypeEntry *
TypeSystemParser::parseNamespaceTypeEntry(const QXmlStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
- QScopedPointer<NamespaceTypeEntry> result(new NamespaceTypeEntry(name, since));
- applyCommonAttributes(result.data(), attributes);
- applyComplexTypeAttributes(reader, result.data(), attributes);
+ if (!checkRootElement())
+ return nullptr;
+ QScopedPointer<NamespaceTypeEntry> result(new NamespaceTypeEntry(name, since, currentParentTypeEntry()));
+ auto visibility = TypeSystem::Visibility::Unspecified;
+ applyCommonAttributes(reader, result.data(), attributes);
for (int i = attributes->size() - 1; i >= 0; --i) {
const QStringRef attributeName = attributes->at(i).qualifiedName();
if (attributeName == QLatin1String("files")) {
@@ -1304,9 +1370,26 @@ NamespaceTypeEntry *
return nullptr;
}
result->setExtends(*extendsIt);
+ } else if (attributeName == visibleAttribute()) {
+ const auto attribute = attributes->takeAt(i);
+ visibility = visibilityFromAttribute(attribute.value());
+ if (visibility == TypeSystem::Visibility::Unspecified) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgInvalidAttributeValue(attribute)));
+ }
+ } else if (attributeName == generateAttribute()) {
+ if (!convertBoolean(attributes->takeAt(i).value(), generateAttribute(), true))
+ visibility = TypeSystem::Visibility::Invisible;
+ } else if (attributeName == generateUsingAttribute()) {
+ result->setGenerateUsing(convertBoolean(attributes->takeAt(i).value(), generateUsingAttribute(), true));
}
}
+ if (visibility != TypeSystem::Visibility::Unspecified)
+ result->setVisibility(visibility);
+ // Handle legacy "generate" before the common handling
+ applyComplexTypeAttributes(reader, result.data(), attributes);
+
if (result->extends() && !result->hasPattern()) {
m_error = msgExtendingNamespaceRequiresPattern(name);
return nullptr;
@@ -1316,12 +1399,14 @@ NamespaceTypeEntry *
}
ValueTypeEntry *
- TypeSystemParser::parseValueTypeEntry(const QXmlStreamReader &,
+ TypeSystemParser::parseValueTypeEntry(const QXmlStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
- auto *typeEntry = new ValueTypeEntry(name, since);
- applyCommonAttributes(typeEntry, attributes);
+ if (!checkRootElement())
+ return nullptr;
+ auto *typeEntry = new ValueTypeEntry(name, since, currentParentTypeEntry());
+ applyCommonAttributes(reader, typeEntry, attributes);
const int defaultCtIndex =
indexOfAttribute(*attributes, u"default-constructor");
if (defaultCtIndex != -1)
@@ -1330,10 +1415,12 @@ ValueTypeEntry *
}
FunctionTypeEntry *
- TypeSystemParser::parseFunctionTypeEntry(const QXmlStreamReader &,
+ TypeSystemParser::parseFunctionTypeEntry(const QXmlStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
+ if (!checkRootElement())
+ return nullptr;
const int signatureIndex = indexOfAttribute(*attributes, signatureAttribute());
if (signatureIndex == -1) {
m_error = msgMissingAttribute(signatureAttribute());
@@ -1345,8 +1432,8 @@ FunctionTypeEntry *
TypeEntry *existingType = m_database->findType(name);
if (!existingType) {
- auto *result = new FunctionTypeEntry(name, signature, since);
- applyCommonAttributes(result, attributes);
+ auto *result = new FunctionTypeEntry(name, signature, since, currentParentTypeEntry());
+ applyCommonAttributes(reader, result, attributes);
return result;
}
@@ -1362,10 +1449,13 @@ FunctionTypeEntry *
}
TypedefEntry *
- TypeSystemParser::parseTypedefEntry(const QXmlStreamReader &, const QString &name,
- const QVersionNumber &since,
- QXmlStreamAttributes *attributes)
+ TypeSystemParser::parseTypedefEntry(const QXmlStreamReader &reader,
+ const QString &name,
+ const QVersionNumber &since,
+ QXmlStreamAttributes *attributes)
{
+ if (!checkRootElement())
+ return nullptr;
if (m_current && m_current->type != StackElement::Root
&& m_current->type != StackElement::NamespaceTypeEntry) {
m_error = QLatin1String("typedef entries must be nested in namespaces or type system.");
@@ -1377,8 +1467,8 @@ TypedefEntry *
return nullptr;
}
const QString sourceType = attributes->takeAt(sourceIndex).value().toString();
- auto result = new TypedefEntry(name, sourceType, since);
- applyCommonAttributes(result, attributes);
+ auto result = new TypedefEntry(name, sourceType, since, currentParentTypeEntry());
+ applyCommonAttributes(reader, result, attributes);
return result;
}
@@ -1407,7 +1497,7 @@ void TypeSystemParser::applyComplexTypeAttributes(const QXmlStreamReader &reader
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
const bool v = convertBoolean(attributes->takeAt(i).value(), genericClassAttribute(), false);
ctype->setGenericClass(v);
- } else if (name == QLatin1String("target-lang-name")) {
+ } else if (name == targetLangNameAttribute()) {
ctype->setTargetLangName(attributes->takeAt(i).value().toString());
} else if (name == QLatin1String("polymorphic-base")) {
ctype->setPolymorphicIdValue(attributes->takeAt(i).value().toString());
@@ -1462,13 +1552,10 @@ void TypeSystemParser::applyComplexTypeAttributes(const QXmlStreamReader &reader
if (ctype->type() != TypeEntry::ContainerType)
ctype->setTargetLangPackage(package);
- if (InterfaceTypeEntry *di = ctype->designatedInterface())
- di->setTargetLangPackage(package);
-
if (generate)
ctype->setCodeGeneration(m_generate);
else
- ctype->setCodeGeneration(TypeEntry::GenerateForSubclass);
+ ctype->setCodeGeneration(TypeEntry::GenerationDisabled);
}
bool TypeSystemParser::parseRenameFunction(const QXmlStreamReader &,
@@ -1618,8 +1705,10 @@ TypeSystemTypeEntry *TypeSystemParser::parseRootElement(const QXmlStreamReader &
auto *moduleEntry =
const_cast<TypeSystemTypeEntry *>(m_database->findTypeSystemType(m_defaultPackage));
const bool add = moduleEntry == nullptr;
- if (add)
- moduleEntry = new TypeSystemTypeEntry(m_defaultPackage, since);
+ if (add) {
+ moduleEntry = new TypeSystemTypeEntry(m_defaultPackage, since,
+ currentParentTypeEntry());
+ }
moduleEntry->setCodeGeneration(m_generate);
if ((m_generate == TypeEntry::GenerateForSubclass ||
@@ -1649,7 +1738,7 @@ bool TypeSystemParser::loadTypesystem(const QXmlStreamReader &,
}
const bool result =
m_database->parseFile(typeSystemName, m_currentPath, generateChild
- && m_generate == TypeEntry::GenerateAll);
+ && m_generate == TypeEntry::GenerateCode);
if (!result)
m_error = QStringLiteral("Failed to parse: '%1'").arg(typeSystemName);
return result;
@@ -2078,6 +2167,18 @@ bool TypeSystemParser::parseModifyField(const QXmlStreamReader &reader,
return true;
}
+static bool parseOverloadNumber(const QXmlStreamAttribute &attribute, int *overloadNumber,
+ QString *errorMessage)
+{
+ bool ok;
+ *overloadNumber = attribute.value().toInt(&ok);
+ if (!ok || *overloadNumber < 0) {
+ *errorMessage = msgInvalidAttributeValue(attribute);
+ return false;
+ }
+ return true;
+}
+
bool TypeSystemParser::parseAddFunction(const QXmlStreamReader &,
const StackElement &topElement,
QXmlStreamAttributes *attributes)
@@ -2091,6 +2192,7 @@ bool TypeSystemParser::parseAddFunction(const QXmlStreamReader &,
QString returnType = QLatin1String("void");
bool staticFunction = false;
QString access;
+ int overloadNumber = TypeSystem::OverloadNumberUnset;
for (int i = attributes->size() - 1; i >= 0; --i) {
const QStringRef name = attributes->at(i).qualifiedName();
if (name == QLatin1String("signature")) {
@@ -2102,6 +2204,9 @@ bool TypeSystemParser::parseAddFunction(const QXmlStreamReader &,
staticAttribute(), false);
} else if (name == accessAttribute()) {
access = attributes->takeAt(i).value().toString();
+ } else if (name == overloadNumberAttribute()) {
+ if (!parseOverloadNumber(attributes->takeAt(i), &overloadNumber, &m_error))
+ return false;
}
}
@@ -2137,6 +2242,7 @@ bool TypeSystemParser::parseAddFunction(const QXmlStreamReader &,
m_contextStack.top()->functionMods.size();
FunctionModification mod;
+ mod.setOverloadNumber(overloadNumber);
if (!mod.setSignature(m_currentSignature, &m_error))
return false;
mod.setOriginalSignature(originalSignature);
@@ -2144,6 +2250,40 @@ bool TypeSystemParser::parseAddFunction(const QXmlStreamReader &,
return true;
}
+bool TypeSystemParser::parseProperty(const QXmlStreamReader &, const StackElement &topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if ((topElement.type & StackElement::ComplexTypeEntryMask) == 0) {
+ m_error = QString::fromLatin1("Add property requires a complex type as parent"
+ ", was=%1").arg(topElement.type, 0, 16);
+ return false;
+ }
+
+ TypeSystemProperty property;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const auto name = attributes->at(i).qualifiedName();
+ if (name == nameAttribute()) {
+ property.name = attributes->takeAt(i).value().toString();
+ } else if (name == QLatin1String("get")) {
+ property.read = attributes->takeAt(i).value().toString();
+ } else if (name == QLatin1String("type")) {
+ property.type = attributes->takeAt(i).value().toString();
+ } else if (name == QLatin1String("set")) {
+ property.write = attributes->takeAt(i).value().toString();
+ } else if (name == generateGetSetDefAttribute()) {
+ property.generateGetSetDef =
+ convertBoolean(attributes->takeAt(i).value(),
+ generateGetSetDefAttribute(), false);
+ }
+ }
+ if (!property.isValid()) {
+ m_error = QLatin1String("<property> element is missing required attibutes (name/type/get).");
+ return false;
+ }
+ static_cast<ComplexTypeEntry *>(topElement.entry)->addProperty(property);
+ return true;
+}
+
bool TypeSystemParser::parseModifyFunction(const QXmlStreamReader &reader,
const StackElement &topElement,
QXmlStreamAttributes *attributes)
@@ -2161,6 +2301,7 @@ bool TypeSystemParser::parseModifyFunction(const QXmlStreamReader &reader,
QString association;
bool deprecated = false;
bool isThread = false;
+ int overloadNumber = TypeSystem::OverloadNumberUnset;
TypeSystem::ExceptionHandling exceptionHandling = TypeSystem::ExceptionHandling::Unspecified;
TypeSystem::AllowThread allowThread = TypeSystem::AllowThread::Unspecified;
for (int i = attributes->size() - 1; i >= 0; --i) {
@@ -2197,6 +2338,9 @@ bool TypeSystemParser::parseModifyFunction(const QXmlStreamReader &reader,
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
+ } else if (name == overloadNumberAttribute()) {
+ if (!parseOverloadNumber(attributes->takeAt(i), &overloadNumber, &m_error))
+ return false;
} else if (name == virtualSlotAttribute()) {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
@@ -2220,6 +2364,7 @@ bool TypeSystemParser::parseModifyFunction(const QXmlStreamReader &reader,
return false;
mod.setOriginalSignature(originalSignature);
mod.setExceptionHandling(exceptionHandling);
+ mod.setOverloadNumber(overloadNumber);
m_currentSignature = signature;
if (!access.isEmpty()) {
@@ -2398,7 +2543,7 @@ bool TypeSystemParser::readFileSnippet(QXmlStreamAttributes *attributes, CodeSni
"// START of custom code block [file: "
<< source << "]\n"
<< extractSnippet(QString::fromUtf8(codeFile.readAll()), snippetLabel)
- << "\n// END of custom code block [file: " << source
+ << "// END of custom code block [file: " << source
<< "]\n// ========================================================================\n";
snip->addCode(content);
return true;
@@ -2443,19 +2588,8 @@ bool TypeSystemParser::parseInjectCode(const QXmlStreamReader &,
snip.position = position;
snip.language = lang;
- if (snip.language == TypeSystem::Interface
- && topElement.type != StackElement::InterfaceTypeEntry) {
- m_error = QLatin1String("Interface code injections must be direct child of an interface type entry");
- return false;
- }
-
if (topElement.type == StackElement::ModifyFunction
|| topElement.type == StackElement::AddFunction) {
- if (snip.language == TypeSystem::ShellDeclaration) {
- m_error = QLatin1String("no function implementation in shell declaration in which to inject code");
- return false;
- }
-
FunctionModification &mod = m_contextStack.top()->functionMods.last();
mod.snips << snip;
if (!snip.code().isEmpty())
@@ -2477,7 +2611,7 @@ bool TypeSystemParser::parseInclude(const QXmlStreamReader &,
QString location;
for (int i = attributes->size() - 1; i >= 0; --i) {
const QStringRef name = attributes->at(i).qualifiedName();
- if (name == QLatin1String("file-name"))
+ if (name == fileNameAttribute())
fileName = attributes->takeAt(i).value().toString();
else if (name == locationAttribute())
location = attributes->takeAt(i).value().toString();
@@ -2498,10 +2632,18 @@ bool TypeSystemParser::parseInclude(const QXmlStreamReader &,
m_error = QLatin1String("Only supported parent tags are primitive-type, complex types or extra-includes");
return false;
}
- if (InterfaceTypeEntry *di = entry->designatedInterface()) {
- di->setInclude(entry->include());
- di->setExtraIncludes(entry->extraIncludes());
+ return true;
+}
+
+bool TypeSystemParser::parseSystemInclude(const QXmlStreamReader &,
+ QXmlStreamAttributes *attributes)
+{
+ const int index = indexOfAttribute(*attributes, fileNameAttribute());
+ if (index == -1) {
+ m_error = msgMissingAttribute(fileNameAttribute());
+ return false;
}
+ TypeDatabase::instance()->addSystemInclude(attributes->takeAt(index).value().toString());
return true;
}
@@ -2550,6 +2692,17 @@ bool TypeSystemParser::parseReplace(const QXmlStreamReader &,
return true;
}
+static bool parseVersion(const QString &versionSpec, const QString &package,
+ QVersionNumber *result, QString *errorMessage)
+{
+ *result = QVersionNumber::fromString(versionSpec);
+ if (result->isNull()) {
+ *errorMessage = msgInvalidVersion(versionSpec, package);
+ return false;
+ }
+ return true;
+}
+
bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
{
if (m_ignoreDepth) {
@@ -2560,20 +2713,25 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
const QStringRef tagName = reader.name();
QXmlStreamAttributes attributes = reader.attributes();
- QVersionNumber since(0, 0);
- int index = indexOfAttribute(attributes, sinceAttribute());
- if (index != -1) {
- const QStringRef sinceSpec = attributes.takeAt(index).value();
- since = QVersionNumber::fromString(sinceSpec.toString());
- if (since.isNull()) {
- m_error = msgInvalidVersion(sinceSpec, m_defaultPackage);
- return false;
+ VersionRange versionRange;
+ for (int i = attributes.size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes.at(i).qualifiedName();
+ if (name == sinceAttribute()) {
+ if (!parseVersion(attributes.takeAt(i).value().toString(),
+ m_defaultPackage, &versionRange.since, &m_error)) {
+ return false;
+ }
+ } else if (name == untilAttribute()) {
+ if (!parseVersion(attributes.takeAt(i).value().toString(),
+ m_defaultPackage, &versionRange.until, &m_error)) {
+ return false;
+ }
}
}
- if (!m_defaultPackage.isEmpty() && since > QVersionNumber(0, 0)) {
+ if (!m_defaultPackage.isEmpty() && !versionRange.isNull()) {
TypeDatabase* td = TypeDatabase::instance();
- if (!td->checkApiVersion(m_defaultPackage, since)) {
+ if (!td->checkApiVersion(m_defaultPackage, versionRange)) {
++m_ignoreDepth;
return true;
}
@@ -2596,7 +2754,7 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
auto *element = new StackElement(m_current);
element->type = elementType;
- if (element->type == StackElement::Root && m_generate == TypeEntry::GenerateAll)
+ if (element->type == StackElement::Root && m_generate == TypeEntry::GenerateCode)
customConversionsForReview.clear();
if (element->type == StackElement::CustomMetaConstructor
@@ -2630,18 +2788,22 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
return false;
}
}
+ // Allow for primitive and/or std:: types only, else require proper nesting.
+ if (element->type != StackElement::PrimitiveTypeEntry && name.contains(QLatin1Char(':'))
+ && !name.contains(QLatin1String("std::"))) {
+ m_error = msgIncorrectlyNestedName(name);
+ return false;
+ }
if (m_database->hasDroppedTypeEntries()) {
- QString identifier = getNamePrefix(element) + QLatin1Char('.');
- identifier += element->type == StackElement::FunctionTypeEntry
- ? attributes.value(signatureAttribute()).toString()
- : name;
- if (m_database->shouldDropTypeEntry(identifier)) {
+ const QString identifier = element->type == StackElement::FunctionTypeEntry
+ ? attributes.value(signatureAttribute()).toString() : name;
+ if (shouldDropTypeEntry(m_database, element, identifier)) {
m_currentDroppedEntry = element;
m_currentDroppedEntryDepth = 1;
if (ReportHandler::isDebug(ReportHandler::SparseDebug)) {
- qCDebug(lcShiboken)
- << QStringLiteral("Type system entry '%1' was intentionally dropped from generation.").arg(identifier);
+ qCInfo(lcShiboken, "Type system entry '%s' was intentionally dropped from generation.",
+ qPrintable(identifier));
}
return true;
}
@@ -2677,13 +2839,6 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
}
}
- // Fix type entry name using nesting information.
- if (element->type & StackElement::TypeEntryMask
- && element->parent && element->parent->type != StackElement::Root) {
- name = element->parent->entry->name() + colonColon() + name;
- }
-
-
if (name.isEmpty()) {
m_error = QLatin1String("no 'name' attribute specified");
return false;
@@ -2691,15 +2846,17 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
switch (element->type) {
case StackElement::CustomTypeEntry:
- element->entry = new TypeEntry(name, TypeEntry::CustomType, since);
+ if (!checkRootElement())
+ return false;
+ element->entry = new TypeEntry(name, TypeEntry::CustomType, versionRange.since, m_current->entry);
break;
case StackElement::PrimitiveTypeEntry:
- element->entry = parsePrimitiveTypeEntry(reader, name, since, &attributes);
+ element->entry = parsePrimitiveTypeEntry(reader, name, versionRange.since, &attributes);
if (Q_UNLIKELY(!element->entry))
return false;
break;
case StackElement::ContainerTypeEntry:
- if (ContainerTypeEntry *ce = parseContainerTypeEntry(reader, name, since, &attributes)) {
+ if (ContainerTypeEntry *ce = parseContainerTypeEntry(reader, name, versionRange.since, &attributes)) {
applyComplexTypeAttributes(reader, ce, &attributes);
element->entry = ce;
} else {
@@ -2708,7 +2865,7 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
break;
case StackElement::SmartPointerTypeEntry:
- if (SmartPointerTypeEntry *se = parseSmartPointerEntry(reader, name, since, &attributes)) {
+ if (SmartPointerTypeEntry *se = parseSmartPointerEntry(reader, name, versionRange.since, &attributes)) {
applyComplexTypeAttributes(reader, se, &attributes);
element->entry = se;
} else {
@@ -2716,22 +2873,14 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
}
break;
case StackElement::EnumTypeEntry:
- m_currentEnum = parseEnumTypeEntry(reader, name, since, &attributes);
+ m_currentEnum = parseEnumTypeEntry(reader, name, versionRange.since, &attributes);
if (Q_UNLIKELY(!m_currentEnum))
return false;
element->entry = m_currentEnum;
break;
- case StackElement::InterfaceTypeEntry:
- if (ObjectTypeEntry *oe = parseInterfaceTypeEntry(reader, name, since, &attributes)) {
- applyComplexTypeAttributes(reader, oe, &attributes);
- element->entry = oe;
- } else {
- return false;
- }
- break;
case StackElement::ValueTypeEntry:
- if (ValueTypeEntry *ve = parseValueTypeEntry(reader, name, since, &attributes)) {
+ if (ValueTypeEntry *ve = parseValueTypeEntry(reader, name, versionRange.since, &attributes)) {
applyComplexTypeAttributes(reader, ve, &attributes);
element->entry = ve;
} else {
@@ -2739,23 +2888,26 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
}
break;
case StackElement::NamespaceTypeEntry:
- if (auto entry = parseNamespaceTypeEntry(reader, name, since, &attributes))
+ if (auto entry = parseNamespaceTypeEntry(reader, name, versionRange.since, &attributes))
element->entry = entry;
else
return false;
break;
case StackElement::ObjectTypeEntry:
- element->entry = new ObjectTypeEntry(name, since);
- applyCommonAttributes(element->entry, &attributes);
+ case StackElement::InterfaceTypeEntry:
+ if (!checkRootElement())
+ return false;
+ element->entry = new ObjectTypeEntry(name, versionRange.since, currentParentTypeEntry());
+ applyCommonAttributes(reader, element->entry, &attributes);
applyComplexTypeAttributes(reader, static_cast<ComplexTypeEntry *>(element->entry), &attributes);
break;
case StackElement::FunctionTypeEntry:
- element->entry = parseFunctionTypeEntry(reader, name, since, &attributes);
+ element->entry = parseFunctionTypeEntry(reader, name, versionRange.since, &attributes);
if (Q_UNLIKELY(!element->entry))
return false;
break;
case StackElement::TypedefTypeEntry:
- if (TypedefEntry *te = parseTypedefEntry(reader, name, since, &attributes)) {
+ if (TypedefEntry *te = parseTypedefEntry(reader, name, versionRange.since, &attributes)) {
applyComplexTypeAttributes(reader, te, &attributes);
element->entry = te;
} else {
@@ -2764,7 +2916,7 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
break;
default:
Q_ASSERT(false);
- };
+ }
if (element->entry) {
if (!m_database->addType(element->entry, &m_error))
@@ -2787,6 +2939,7 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
|| element->type == StackElement::LoadTypesystem
|| element->type == StackElement::InjectCode
|| element->type == StackElement::ExtraIncludes
+ || element->type == StackElement::SystemInclude
|| element->type == StackElement::ConversionRule
|| element->type == StackElement::AddFunction
|| element->type == StackElement::Template;
@@ -2801,7 +2954,7 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
switch (element->type) {
case StackElement::Root:
- element->entry = parseRootElement(reader, since, &attributes);
+ element->entry = parseRootElement(reader, versionRange.since, &attributes);
element->type = StackElement::Root;
break;
case StackElement::LoadTypesystem:
@@ -2896,6 +3049,10 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
if (!parseAddFunction(reader, topElement, &attributes))
return false;
break;
+ case StackElement::Property:
+ if (!parseProperty(reader, topElement, &attributes))
+ return false;
+ break;
case StackElement::ModifyFunction:
if (!parseModifyFunction(reader, topElement, &attributes))
return false;
@@ -2939,6 +3096,10 @@ bool TypeSystemParser::startElement(const QXmlStreamReader &reader)
if (!addRejection(m_database, &attributes, &m_error))
return false;
break;
+ case StackElement::SystemInclude:
+ if (!parseSystemInclude(reader, &attributes))
+ return false;
+ break;
case StackElement::Template: {
const int nameIndex = indexOfAttribute(attributes, nameAttribute());
if (nameIndex == -1) {