aboutsummaryrefslogtreecommitdiffstats
path: root/ApiExtractor/typesystem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ApiExtractor/typesystem.cpp')
-rw-r--r--ApiExtractor/typesystem.cpp161
1 files changed, 99 insertions, 62 deletions
diff --git a/ApiExtractor/typesystem.cpp b/ApiExtractor/typesystem.cpp
index 79156cd07..0575b3224 100644
--- a/ApiExtractor/typesystem.cpp
+++ b/ApiExtractor/typesystem.cpp
@@ -30,7 +30,10 @@
#include "typesystem_p.h"
#include "typedatabase.h"
#include "reporthandler.h"
-#include <QtXml/QtXml>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QXmlStreamAttributes>
+#include <QtCore/QXmlStreamReader>
static QString strings_Object = QLatin1String("Object");
static QString strings_String = QLatin1String("String");
@@ -39,6 +42,11 @@ static QString strings_jchar = QLatin1String("jchar");
static QString strings_jobject = QLatin1String("jobject");
static inline QString colonColon() { return QStringLiteral("::"); }
+static inline QString quoteAfterLineAttribute() { return QStringLiteral("quote-after-line"); }
+static inline QString quoteBeforeLineAttribute() { return QStringLiteral("quote-before-line"); }
+static inline QString nameAttribute() { return QStringLiteral("name"); }
+static inline QString sinceAttribute() { return QStringLiteral("since"); }
+static inline QString flagsAttribute() { return QStringLiteral("flags"); }
static QList<CustomConversion*> customConversionsForReview = QList<CustomConversion*>();
@@ -97,49 +105,80 @@ Handler::Handler(TypeDatabase* database, bool generate)
tagNames.insert(QLatin1String("add-function"), StackElement::AddFunction);
}
-bool Handler::error(const QXmlParseException &e)
+static QString msgReaderError(const QXmlStreamReader &reader, const QString &what)
{
- qWarning("Error: line=%d, column=%d, message=%s\n",
- e.lineNumber(), e.columnNumber(), qPrintable(e.message()));
- return false;
+ QString message;
+ QTextStream str(&message);
+ str << "Error: ";
+ if (const QFile *file = qobject_cast<const QFile *>(reader.device()))
+ str << "file=" << QDir::toNativeSeparators(file->fileName()) << ", ";
+ str << "line=" << reader.lineNumber() << ", column=" << reader.columnNumber()
+ << ", message=" << what;
+ return message;
}
-bool Handler::fatalError(const QXmlParseException &e)
+static QString msgReaderError(const QXmlStreamReader &reader)
{
- qWarning("Fatal error: line=%d, column=%d, message=%s\n",
- e.lineNumber(), e.columnNumber(), qPrintable(e.message()));
-
- return false;
+ return msgReaderError(reader, reader.errorString());
}
-bool Handler::warning(const QXmlParseException &e)
+bool Handler::parse(QXmlStreamReader &reader)
{
- qWarning("Warning: line=%d, column=%d, message=%s\n",
- e.lineNumber(), e.columnNumber(), qPrintable(e.message()));
+ m_error.clear();
+ while (!reader.atEnd()) {
+ switch (reader.readNext()) {
+ case QXmlStreamReader::NoToken:
+ case QXmlStreamReader::Invalid:
+ qCWarning(lcShiboken).noquote().nospace() << msgReaderError(reader);
+ return false;
+ case QXmlStreamReader::StartElement:
+ if (!startElement(reader.name(), reader.attributes())) {
+ m_error = msgReaderError(reader, m_error);
+ return false;
+ }
- return false;
+ break;
+ case QXmlStreamReader::EndElement:
+ if (!endElement(reader.name())) {
+ m_error = msgReaderError(reader, m_error);
+ return false;
+ }
+ break;
+ case QXmlStreamReader::Characters:
+ if (!characters(reader.text().toString())) {
+ m_error = msgReaderError(reader, m_error);
+ return false;
+ }
+ break;
+ case QXmlStreamReader::StartDocument:
+ case QXmlStreamReader::EndDocument:
+ case QXmlStreamReader::Comment:
+ case QXmlStreamReader::DTD:
+ case QXmlStreamReader::EntityReference:
+ case QXmlStreamReader::ProcessingInstruction:
+ break;
+ }
+ }
+ return true;
}
-void Handler::fetchAttributeValues(const QString &name, const QXmlAttributes &atts,
+void Handler::fetchAttributeValues(const QString &name, const QXmlStreamAttributes &atts,
QHash<QString, QString> *acceptedAttributes)
{
Q_ASSERT(acceptedAttributes);
for (int i = 0; i < atts.length(); ++i) {
- QString key = atts.localName(i).toLower();
- QString val = atts.value(i);
-
+ const QString key = atts.at(i).name().toString().toLower();
if (!acceptedAttributes->contains(key)) {
qCWarning(lcShiboken).noquote().nospace()
<< QStringLiteral("Unknown attribute for '%1': '%2'").arg(name, key);
} else {
- (*acceptedAttributes)[key] = val;
+ acceptedAttributes->insert(key, atts.at(i).value().toString());
}
-
}
}
-bool Handler::endElement(const QString &, const QString &localName, const QString &)
+bool Handler::endElement(const QStringRef &localName)
{
if (m_ignoreDepth) {
--m_ignoreDepth;
@@ -158,8 +197,7 @@ bool Handler::endElement(const QString &, const QString &localName, const QStrin
return true;
}
- QString tagName = localName.toLower();
- if (tagName == QLatin1String("import-file"))
+ if (!localName.compare(QLatin1String("import-file"), Qt::CaseInsensitive))
return true;
if (!m_current)
@@ -343,9 +381,9 @@ bool Handler::characters(const QString &ch)
return true;
}
-bool Handler::importFileElement(const QXmlAttributes &atts)
+bool Handler::importFileElement(const QXmlStreamAttributes &atts)
{
- QString fileName = atts.value(QLatin1String("name"));
+ const QString fileName = atts.value(nameAttribute()).toString();
if (fileName.isEmpty()) {
m_error = QLatin1String("Required attribute 'name' missing for include-file tag.");
return false;
@@ -360,11 +398,11 @@ bool Handler::importFileElement(const QXmlAttributes &atts)
}
}
- QString quoteFrom = atts.value(QLatin1String("quote-after-line"));
+ const QStringRef quoteFrom = atts.value(quoteAfterLineAttribute());
bool foundFromOk = quoteFrom.isEmpty();
bool from = quoteFrom.isEmpty();
- QString quoteTo = atts.value(QLatin1String("quote-before-line"));
+ const QStringRef quoteTo = atts.value(quoteBeforeLineAttribute());
bool foundToOk = quoteTo.isEmpty();
bool to = true;
@@ -385,9 +423,9 @@ bool Handler::importFileElement(const QXmlAttributes &atts)
}
if (!foundFromOk || !foundToOk) {
QString fromError = QStringLiteral("Could not find quote-after-line='%1' in file '%2'.")
- .arg(quoteFrom, fileName);
+ .arg(quoteFrom.toString(), fileName);
QString toError = QStringLiteral("Could not find quote-before-line='%1' in file '%2'.")
- .arg(quoteTo, fileName);
+ .arg(quoteTo.toString(), fileName);
if (!foundToOk)
m_error = toError;
@@ -497,28 +535,27 @@ void Handler::addFlags(const QString &name, QString flagName,
setTypeRevision(ftype, revision.toInt());
}
-bool Handler::startElement(const QString &, const QString &n,
- const QString &, const QXmlAttributes &atts)
+bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts)
{
if (m_ignoreDepth) {
++m_ignoreDepth;
return true;
}
- if (!m_defaultPackage.isEmpty() && atts.index(QLatin1String("since")) != -1) {
+ if (!m_defaultPackage.isEmpty() && atts.hasAttribute(sinceAttribute())) {
TypeDatabase* td = TypeDatabase::instance();
- if (!td->checkApiVersion(m_defaultPackage, atts.value(QLatin1String("since")).toUtf8())) {
+ if (!td->checkApiVersion(m_defaultPackage, atts.value(sinceAttribute()).toUtf8())) {
++m_ignoreDepth;
return true;
}
}
-
- QString tagName = n.toLower();
+ const QString tagName = n.toString().toLower();
if (tagName == QLatin1String("import-file"))
return importFileElement(atts);
- if (!tagNames.contains(tagName)) {
+ const QHash<QString, StackElement::ElementType>::const_iterator tit = tagNames.constFind(tagName);
+ if (tit == tagNames.constEnd()) {
m_error = QStringLiteral("Unknown tag name: '%1'").arg(tagName);
return false;
}
@@ -529,7 +566,7 @@ bool Handler::startElement(const QString &, const QString &n,
}
StackElement* element = new StackElement(m_current);
- element->type = tagNames[tagName];
+ element->type = tit.value();
if (element->type == StackElement::Root && m_generate == TypeEntry::GenerateAll)
customConversionsForReview.clear();
@@ -545,9 +582,9 @@ bool Handler::startElement(const QString &, const QString &n,
if (element->type & StackElement::TypeEntryMask) {
QHash<QString, QString> attributes;
- attributes.insert(QLatin1String("name"), QString());
+ attributes.insert(nameAttribute(), QString());
attributes.insert(QLatin1String("revision"), QLatin1String("0"));
- attributes.insert(QLatin1String("since"), QLatin1String("0"));
+ attributes.insert(sinceAttribute(), QLatin1String("0"));
switch (element->type) {
case StackElement::PrimitiveTypeEntry:
@@ -561,7 +598,7 @@ bool Handler::startElement(const QString &, const QString &n,
attributes.insert(QLatin1String("type"), QString());
break;
case StackElement::EnumTypeEntry:
- attributes.insert(QLatin1String("flags"), QString());
+ attributes.insert(flagsAttribute(), QString());
attributes.insert(QLatin1String("flags-revision"), QString());
attributes.insert(QLatin1String("upper-bound"), QString());
attributes.insert(QLatin1String("lower-bound"), QString());
@@ -604,8 +641,8 @@ bool Handler::startElement(const QString &, const QString &n,
};
fetchAttributeValues(tagName, atts, &attributes);
- QString name = attributes[QLatin1String("name")];
- double since = attributes[QLatin1String("since")].toDouble();
+ QString name = attributes[nameAttribute()];
+ double since = attributes[sinceAttribute()].toDouble();
if (m_database->hasDroppedTypeEntries()) {
QString identifier = getNamePrefix(element) + QLatin1Char('.');
@@ -749,7 +786,7 @@ bool Handler::startElement(const QString &, const QString &n,
m_currentEnum->setExtensible(convertBoolean(attributes[QLatin1String("extensible")], QLatin1String("extensible"), false));
// put in the flags parallel...
- const QString flagNames = attributes[QLatin1String("flags")];
+ const QString flagNames = attributes.value(flagsAttribute());
if (!flagNames.isEmpty()) {
foreach (const QString &flagName, flagNames.split(QLatin1Char(',')))
addFlags(name, flagName.trimmed(), attributes, since);
@@ -899,10 +936,10 @@ bool Handler::startElement(const QString &, const QString &n,
QHash<QString, QString> attributes;
attributes.insert(QLatin1String("mode"), QLatin1String("replace"));
attributes.insert(QLatin1String("format"), QLatin1String("native"));
- attributes.insert(QLatin1String("since"), QLatin1String("0"));
+ attributes.insert(sinceAttribute(), QLatin1String("0"));
fetchAttributeValues(tagName, atts, &attributes);
- double since = attributes[QLatin1String("since")].toDouble();
+ double since = attributes[sinceAttribute()].toDouble();
const int validParent = StackElement::TypeEntryMask
| StackElement::ModifyFunction
@@ -947,9 +984,9 @@ bool Handler::startElement(const QString &, const QString &n,
// check the XML tag attributes
QHash<QString, QString> attributes;
attributes.insert(QLatin1String("xpath"), QString());
- attributes.insert(QLatin1String("since"), QLatin1String("0"));
+ attributes.insert(sinceAttribute(), QLatin1String("0"));
fetchAttributeValues(tagName, atts, &attributes);
- double since = attributes[QLatin1String("since")].toDouble();
+ double since = attributes[sinceAttribute()].toDouble();
const int validParent = StackElement::TypeEntryMask
| StackElement::ModifyFunction
@@ -982,14 +1019,14 @@ bool Handler::startElement(const QString &, const QString &n,
element->entry = topElement.entry;
QHash<QString, QString> attributes;
- attributes.insert(QLatin1String("since"), QLatin1String("0"));
+ attributes.insert(sinceAttribute(), QLatin1String("0"));
switch (element->type) {
case StackElement::Root:
attributes.insert(QLatin1String("package"), QString());
attributes.insert(QLatin1String("default-superclass"), QString());
break;
case StackElement::LoadTypesystem:
- attributes.insert(QLatin1String("name"), QString());
+ attributes.insert(nameAttribute(), QString());
attributes.insert(QLatin1String("generate"), QLatin1String("yes"));
break;
case StackElement::NoNullPointers:
@@ -1028,7 +1065,7 @@ bool Handler::startElement(const QString &, const QString &n,
attributes.insert(QLatin1String("invalidate-after-use"), QLatin1String("no"));
break;
case StackElement::ModifyField:
- attributes.insert(QLatin1String("name"), QString());
+ attributes.insert(nameAttribute(), QString());
attributes.insert(QLatin1String("write"), QLatin1String("true"));
attributes.insert(QLatin1String("read"), QLatin1String("true"));
attributes.insert(QLatin1String("remove"), QString());
@@ -1041,11 +1078,11 @@ bool Handler::startElement(const QString &, const QString &n,
attributes.insert(QLatin1String("location"), QString());
break;
case StackElement::CustomMetaConstructor:
- attributes[QLatin1String("name")] = topElement.entry->name().toLower() + QLatin1String("_create");
+ attributes[nameAttribute()] = topElement.entry->name().toLower() + QLatin1String("_create");
attributes.insert(QLatin1String("param-name"), QLatin1String("copy"));
break;
case StackElement::CustomMetaDestructor:
- attributes[QLatin1String("name")] = topElement.entry->name().toLower() + QLatin1String("_delete");
+ attributes[nameAttribute()] = topElement.entry->name().toLower() + QLatin1String("_delete");
attributes.insert(QLatin1String("param-name"), QLatin1String("copy"));
break;
case StackElement::ReplaceType:
@@ -1068,7 +1105,7 @@ bool Handler::startElement(const QString &, const QString &n,
attributes.insert(QLatin1String("check"), QString());
break;
case StackElement::RejectEnumValue:
- attributes.insert(QLatin1String("name"), QString());
+ attributes.insert(nameAttribute(), QString());
break;
case StackElement::ArgumentMap:
attributes.insert(QLatin1String("index"), QLatin1String("1"));
@@ -1087,10 +1124,10 @@ bool Handler::startElement(const QString &, const QString &n,
attributes.insert(QLatin1String("class"), QLatin1String("all"));
break;
case StackElement::Template:
- attributes.insert(QLatin1String("name"), QString());
+ attributes.insert(nameAttribute(), QString());
break;
case StackElement::TemplateInstanceEnum:
- attributes.insert(QLatin1String("name"), QString());
+ attributes.insert(nameAttribute(), QString());
break;
case StackElement::Replace:
attributes.insert(QLatin1String("from"), QString());
@@ -1110,7 +1147,7 @@ bool Handler::startElement(const QString &, const QString &n,
double since = 0;
if (attributes.count() > 0) {
fetchAttributeValues(tagName, atts, &attributes);
- since = attributes[QLatin1String("since")].toDouble();
+ since = attributes[sinceAttribute()].toDouble();
}
switch (element->type) {
@@ -1133,7 +1170,7 @@ bool Handler::startElement(const QString &, const QString &n,
m_database->addType(element->entry);
break;
case StackElement::LoadTypesystem: {
- QString name = attributes[QLatin1String("name")];
+ QString name = attributes[nameAttribute()];
if (name.isEmpty()) {
m_error = QLatin1String("No typesystem name specified");
return false;
@@ -1150,7 +1187,7 @@ bool Handler::startElement(const QString &, const QString &n,
m_error = QLatin1String("<reject-enum-value> node must be used inside a <enum-type> node");
return false;
}
- QString name = attributes[QLatin1String("name")];
+ QString name = attributes[nameAttribute()];
} break;
case StackElement::ReplaceType: {
if (topElement.type != StackElement::ModifyArgument) {
@@ -1474,7 +1511,7 @@ bool Handler::startElement(const QString &, const QString &n,
break;
case StackElement::ModifyField: {
- QString name = attributes[QLatin1String("name")];
+ QString name = attributes[nameAttribute()];
if (name.isEmpty())
break;
FieldModification fm;
@@ -1621,7 +1658,7 @@ bool Handler::startElement(const QString &, const QString &n,
break;
case StackElement::CustomMetaConstructor:
case StackElement::CustomMetaDestructor: {
- CustomFunction *func = new CustomFunction(attributes[QLatin1String("name")]);
+ CustomFunction *func = new CustomFunction(attributes[nameAttribute()]);
func->paramName = attributes[QLatin1String("param-name")];
element->value.customFunction = func;
}
@@ -1845,7 +1882,7 @@ bool Handler::startElement(const QString &, const QString &n,
}
break;
case StackElement::Template:
- element->value.templateEntry = new TemplateEntry(attributes[QLatin1String("name")], since);
+ element->value.templateEntry = new TemplateEntry(attributes[nameAttribute()], since);
break;
case StackElement::TemplateInstanceEnum:
if (!(topElement.type & StackElement::CodeSnipMask) &&
@@ -1859,7 +1896,7 @@ bool Handler::startElement(const QString &, const QString &n,
"custom-destructors, conversion-rule, native-to-target or add-conversion tags.");
return false;
}
- element->value.templateInstance = new TemplateInstance(attributes[QLatin1String("name")], since);
+ element->value.templateInstance = new TemplateInstance(attributes[nameAttribute()], since);
break;
case StackElement::Replace:
if (topElement.type != StackElement::TemplateInstanceEnum) {