/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt for Python. ** ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "typesystem.h" #include "typedatabase.h" #include "messages.h" #include #include #include #include static QString strings_Object = QLatin1String("Object"); static QString strings_String = QLatin1String("String"); static QString strings_char = QLatin1String("char"); static QString strings_jchar = QLatin1String("jchar"); static QString strings_jobject = QLatin1String("jobject"); static inline QString callOperator() { return QStringLiteral("operator()"); } PrimitiveTypeEntry::PrimitiveTypeEntry(const QString &name, const QVersionNumber &vr) : TypeEntry(name, PrimitiveType, vr), m_preferredTargetLangType(true) { } QString PrimitiveTypeEntry::targetLangName() const { return m_targetLangName; } QString PrimitiveTypeEntry::targetLangApiName() const { return m_targetLangApiName; } PrimitiveTypeEntry *PrimitiveTypeEntry::basicReferencedTypeEntry() const { if (!m_referencedTypeEntry) return nullptr; PrimitiveTypeEntry *baseReferencedTypeEntry = m_referencedTypeEntry->basicReferencedTypeEntry(); return baseReferencedTypeEntry ? baseReferencedTypeEntry : m_referencedTypeEntry; } TypeEntry *PrimitiveTypeEntry::clone() const { return new PrimitiveTypeEntry(*this); } PrimitiveTypeEntry::PrimitiveTypeEntry(const PrimitiveTypeEntry &) = default; CodeSnipList TypeEntry::codeSnips() const { return m_codeSnips; } QString Modification::accessModifierString() const { if (isPrivate()) return QLatin1String("private"); if (isProtected()) return QLatin1String("protected"); if (isPublic()) return QLatin1String("public"); if (isFriendly()) return QLatin1String("friendly"); return QString(); } FunctionModificationList ComplexTypeEntry::functionModifications(const QString &signature) const { FunctionModificationList lst; for (int i = 0; i < m_functionMods.count(); ++i) { const FunctionModification &mod = m_functionMods.at(i); if (mod.matches(signature)) lst << mod; } return lst; } FieldModification ComplexTypeEntry::fieldModification(const QString &name) const { for (const auto &fieldMod : m_fieldMods) { if (fieldMod.name == name) return fieldMod; } FieldModification mod; mod.name = name; mod.modifiers = FieldModification::Readable | FieldModification::Writable; return mod; } QString ComplexTypeEntry::targetLangName() const { return m_targetLangName.isEmpty() ? TypeEntry::targetLangName() : m_targetLangName; } void ComplexTypeEntry::setDefaultConstructor(const QString& defaultConstructor) { m_defaultConstructor = defaultConstructor; } QString ComplexTypeEntry::defaultConstructor() const { return m_defaultConstructor; } bool ComplexTypeEntry::hasDefaultConstructor() const { return !m_defaultConstructor.isEmpty(); } TypeEntry *ComplexTypeEntry::clone() const { return new ComplexTypeEntry(*this); } // Take over parameters relevant for typedefs void ComplexTypeEntry::useAsTypedef(const ComplexTypeEntry *source) { TypeEntry::useAsTypedef(source); m_qualifiedCppName = source->m_qualifiedCppName; m_targetLangName = source->m_targetLangName; m_lookupName = source->m_lookupName; m_targetType = source->m_targetType; } ComplexTypeEntry::ComplexTypeEntry(const ComplexTypeEntry &) = default; QString ContainerTypeEntry::targetLangName() const { switch (m_type) { case StringListContainer: return QLatin1String("QStringList"); case ListContainer: return QLatin1String("QList"); case LinkedListContainer: return QLatin1String("QLinkedList"); case VectorContainer: return QLatin1String("QVector"); case StackContainer: return QLatin1String("QStack"); case QueueContainer: return QLatin1String("QQueue"); case SetContainer: return QLatin1String("QSet"); case MapContainer: return QLatin1String("QMap"); case MultiMapContainer: return QLatin1String("QMultiMap"); case HashContainer: return QLatin1String("QHash"); case MultiHashContainer: return QLatin1String("QMultiHash"); case PairContainer: return QLatin1String("QPair"); default: qWarning("bad type... %d", m_type); break; } return QString(); } QString ContainerTypeEntry::qualifiedCppName() const { if (m_type == StringListContainer) return QLatin1String("QStringList"); return ComplexTypeEntry::qualifiedCppName(); } TypeEntry *ContainerTypeEntry::clone() const { return new ContainerTypeEntry(*this); } ContainerTypeEntry::ContainerTypeEntry(const ContainerTypeEntry &) = default; QString EnumTypeEntry::targetLangQualifier() const { TypeEntry *te = TypeDatabase::instance()->findType(m_qualifier); return te ? te->targetLangName() : m_qualifier; } QString EnumTypeEntry::qualifiedTargetLangName() const { QString qualifiedName; QString pkg = targetLangPackage(); QString qualifier = targetLangQualifier(); if (!pkg.isEmpty()) qualifiedName += pkg + QLatin1Char('.'); if (!qualifier.isEmpty()) qualifiedName += qualifier + QLatin1Char('.'); qualifiedName += targetLangName(); return qualifiedName; } QString EnumTypeEntry::targetLangApiName() const { return QLatin1String("jint"); } QString FlagsTypeEntry::targetLangApiName() const { return QLatin1String("jint"); } TypeEntry *EnumTypeEntry::clone() const { return new EnumTypeEntry(*this); } EnumTypeEntry::EnumTypeEntry(const EnumTypeEntry &) = default; TypeEntry *FlagsTypeEntry::clone() const { return new FlagsTypeEntry(*this); } FlagsTypeEntry::FlagsTypeEntry(const FlagsTypeEntry &) = default; QString FlagsTypeEntry::qualifiedTargetLangName() const { return targetLangPackage() + QLatin1Char('.') + m_enum->targetLangQualifier() + QLatin1Char('.') + targetLangName(); } QString FlagsTypeEntry::targetLangName() const { return m_targetLangName; } /*! * The Visual Studio 2002 compiler doesn't support these symbols, * which our typedefs unforntuatly expand to. */ QString fixCppTypeName(const QString &name) { if (name == QLatin1String("long long")) return QLatin1String("qint64"); if (name == QLatin1String("unsigned long long")) return QLatin1String("quint64"); return name; } QString TemplateInstance::expandCode() const { TemplateEntry *templateEntry = TypeDatabase::instance()->findTemplate(m_name); if (!templateEntry) qFatal(" referring to non-existing template '%s'.", qPrintable(m_name)); QString code = templateEntry->code(); for (auto it = replaceRules.cbegin(), end = replaceRules.cend(); it != end; ++it) code.replace(it.key(), it.value()); while (!code.isEmpty() && code.at(code.size() - 1).isSpace()) code.chop(1); QString result = QLatin1String("// TEMPLATE - ") + m_name + QLatin1String(" - START"); if (!code.startsWith(QLatin1Char('\n'))) result += QLatin1Char('\n'); result += code; result += QLatin1String("\n// TEMPLATE - ") + m_name + QLatin1String(" - END"); return result; } QString CodeSnipAbstract::code() const { QString res; for (const CodeSnipFragment &codeFrag : codeList) res.append(codeFrag.code()); return res; } QString CodeSnipFragment::code() const { return m_instance ? m_instance->expandCode() : m_code; } bool FunctionModification::setSignature(const QString &s, QString *errorMessage) { if (s.startsWith(QLatin1Char('^'))) { m_signaturePattern.setPattern(s); if (!m_signaturePattern.isValid()) { if (errorMessage) { *errorMessage = QLatin1String("Invalid signature pattern: \"") + s + QLatin1String("\": ") + m_signaturePattern.errorString(); } return false; } } else { m_signature = s; } return true; } QString FunctionModification::toString() const { QString str = signature() + QLatin1String("->"); if (modifiers & AccessModifierMask) { switch (modifiers & AccessModifierMask) { case Private: str += QLatin1String("private"); break; case Protected: str += QLatin1String("protected"); break; case Public: str += QLatin1String("public"); break; case Friendly: str += QLatin1String("friendly"); break; } } if (modifiers & Final) str += QLatin1String("final"); if (modifiers & NonFinal) str += QLatin1String("non-final"); if (modifiers & Readable) str += QLatin1String("readable"); if (modifiers & Writable) str += QLatin1String("writable"); if (modifiers & CodeInjection) { for (const CodeSnip &s : snips) { str += QLatin1String("\n//code injection:\n"); str += s.code(); } } if (modifiers & Rename) str += QLatin1String("renamed:") + renamedToName; if (modifiers & Deprecated) str += QLatin1String("deprecate"); if (modifiers & ReplaceExpression) str += QLatin1String("replace-expression"); return str; } static AddedFunction::TypeInfo parseType(const QString& signature, int startPos = 0, int *endPos = nullptr, QString *argumentName = nullptr) { AddedFunction::TypeInfo result; static const QRegularExpression regex(QLatin1String("\\w")); Q_ASSERT(regex.isValid()); int length = signature.length(); int start = signature.indexOf(regex, startPos); if (start == -1) { if (signature.midRef(startPos + 1, 3) == QLatin1String("...")) { // varargs if (endPos) *endPos = startPos + 4; result.name = QLatin1String("..."); } else { // error if (endPos) *endPos = length; } return result; } int cantStop = 0; QString paramString; QChar c; int i = start; for (; i < length; ++i) { c = signature[i]; if (c == QLatin1Char('<')) cantStop++; if (c == QLatin1Char('>')) cantStop--; if (cantStop < 0) break; // FIXME: report error? if ((c == QLatin1Char(')') || c == QLatin1Char(',')) && !cantStop) break; paramString += signature[i]; } if (endPos) *endPos = i; // Check default value if (paramString.contains(QLatin1Char('='))) { QStringList lst = paramString.split(QLatin1Char('=')); paramString = lst[0].trimmed(); result.defaultValue = lst[1].trimmed(); } // check constness if (paramString.startsWith(QLatin1String("const "))) { result.isConstant = true; paramString.remove(0, sizeof("const")/sizeof(char)); paramString = paramString.trimmed(); } // Extract argument name from "T* @foo@" const int nameStartPos = paramString.indexOf(QLatin1Char('@')); if (nameStartPos != -1) { const int nameEndPos = paramString.indexOf(QLatin1Char('@'), nameStartPos + 1); if (nameEndPos > nameStartPos) { if (argumentName) *argumentName = paramString.mid(nameStartPos + 1, nameEndPos - nameStartPos - 1); paramString.remove(nameStartPos, nameEndPos - nameStartPos + 1); paramString = paramString.trimmed(); } } // check reference if (paramString.endsWith(QLatin1Char('&'))) { result.isReference = true; paramString.chop(1); paramString = paramString.trimmed(); } // check Indirections while (paramString.endsWith(QLatin1Char('*'))) { result.indirections++; paramString.chop(1); paramString = paramString.trimmed(); } result.name = paramString; return result; } AddedFunction::AddedFunction(QString signature, const QString &returnType) : m_access(Public) { Q_ASSERT(!returnType.isEmpty()); m_returnType = parseType(returnType); signature = signature.trimmed(); // Skip past "operator()(...)" const int parenStartPos = signature.startsWith(callOperator()) ? callOperator().size() : 0; int endPos = signature.indexOf(QLatin1Char('('), parenStartPos); if (endPos < 0) { m_isConst = false; m_name = signature; } else { m_name = signature.left(endPos).trimmed(); int signatureLength = signature.length(); while (endPos < signatureLength) { QString argumentName; TypeInfo arg = parseType(signature, endPos, &endPos, &argumentName); if (!arg.name.isEmpty()) m_arguments.append({argumentName, arg}); // end of parameters... if (endPos >= signatureLength || signature[endPos] == QLatin1Char(')')) break; } // is const? m_isConst = signature.rightRef(signatureLength - endPos).contains(QLatin1String("const")); } } #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const ReferenceCount &r) { QDebugStateSaver saver(d); d.noquote(); d.nospace(); d << "ReferenceCount(" << r.varName << ", action=" << r.action << ')'; return d; } QDebug operator<<(QDebug d, const CodeSnip &s) { QDebugStateSaver saver(d); d.noquote(); d.nospace(); d << "CodeSnip(language=" << s.language << ", position=" << s.position << ", \""; for (const auto &f : s.codeList) { const QString &code = f.code(); const auto lines = code.splitRef(QLatin1Char('\n')); for (int i = 0, size = lines.size(); i < size; ++i) { if (i) d << "\\n"; d << lines.at(i).trimmed(); } } d << '"'; if (!s.argumentMap.isEmpty()) { d << ", argumentMap{"; for (auto it = s.argumentMap.cbegin(), end = s.argumentMap.cend(); it != end; ++it) d << it.key() << "->\"" << it.value() << '"'; d << '}'; } d << ')'; return d; } void Modification::formatDebug(QDebug &d) const { d << "modifiers=" << hex << showbase << modifiers << noshowbase << dec; if (removal) d << ", removal"; if (!renamedToName.isEmpty()) d << ", renamedToName=\"" << renamedToName << '"'; } void FunctionModification::formatDebug(QDebug &d) const { if (m_signature.isEmpty()) d << "pattern=\"" << m_signaturePattern.pattern(); else d << "signature=\"" << m_signature; d << "\", "; Modification::formatDebug(d); if (!association.isEmpty()) d << ", association=\"" << association << '"'; if (m_allowThread != TypeSystem::AllowThread::Unspecified) d << ", allowThread=" << int(m_allowThread); if (m_thread) d << ", thread"; if (m_exceptionHandling != TypeSystem::ExceptionHandling::Unspecified) d << ", exceptionHandling=" << int(m_exceptionHandling); if (!snips.isEmpty()) d << ", snips=(" << snips << ')'; if (!argument_mods.isEmpty()) d << ", argument_mods=(" << argument_mods << ')'; } QDebug operator<<(QDebug d, const ArgumentOwner &a) { QDebugStateSaver saver(d); d.noquote(); d.nospace(); d << "ArgumentOwner(index=" << a.index << ", action=" << a.action << ')'; return d; } QDebug operator<<(QDebug d, const ArgumentModification &a) { QDebugStateSaver saver(d); d.noquote(); d.nospace(); d << "ArgumentModification(index=" << a.index; if (a.removedDefaultExpression) d << ", removedDefaultExpression"; if (a.removed) d << ", removed"; if (a.noNullPointers) d << ", noNullPointers"; if (a.array) d << ", array"; if (!a.referenceCounts.isEmpty()) d << ", referenceCounts=" << a.referenceCounts; if (!a.modified_type.isEmpty()) d << ", modified_type=\"" << a.modified_type << '"'; if (!a.replace_value.isEmpty()) d << ", replace_value=\"" << a.replace_value << '"'; if (!a.replacedDefaultExpression.isEmpty()) d << ", replacedDefaultExpression=\"" << a.replacedDefaultExpression << '"'; if (!a.ownerships.isEmpty()) d << ", ownerships=" << a.ownerships; if (!a.renamed_to.isEmpty()) d << ", renamed_to=\"" << a.renamed_to << '"'; d << ", owner=" << a.owner << ')'; return d; } QDebug operator<<(QDebug d, const FunctionModification &fm) { QDebugStateSaver saver(d); d.noquote(); d.nospace(); d << "FunctionModification("; fm.formatDebug(d); d << ')'; return d; } QDebug operator<<(QDebug d, const AddedFunction::TypeInfo &ti) { QDebugStateSaver saver(d); d.noquote(); d.nospace(); d << "TypeInfo("; if (ti.isConstant) d << "const"; if (ti.indirections) d << QByteArray(ti.indirections, '*'); if (ti.isReference) d << " &"; d << ti.name; if (!ti.defaultValue.isEmpty()) d << " = " << ti.defaultValue; d << ')'; return d; } QDebug operator<<(QDebug d, const AddedFunction::Argument &a) { QDebugStateSaver saver(d); d.noquote(); d.nospace(); d << "Argument("; d << a.typeInfo; if (!a.name.isEmpty()) d << ' ' << a.name; d << ')'; return d; } QDebug operator<<(QDebug d, const AddedFunction &af) { QDebugStateSaver saver(d); d.noquote(); d.nospace(); d << "AddedFunction("; if (af.access() == AddedFunction::Protected) d << "protected"; if (af.isStatic()) d << " static"; d << af.returnType() << ' ' << af.name() << '(' << af.arguments() << ')'; if (af.isConstant()) d << " const"; return d; } #endif // !QT_NO_DEBUG_STREAM AddedFunction::TypeInfo AddedFunction::TypeInfo::fromSignature(const QString& signature) { return parseType(signature); } ComplexTypeEntry::ComplexTypeEntry(const QString &name, TypeEntry::Type t, const QVersionNumber &vr) : TypeEntry(name, t, vr), m_qualifiedCppName(name), m_polymorphicBase(false), m_genericClass(false), m_deleteInMainThread(false) { } bool ComplexTypeEntry::isComplex() const { return true; } QString ComplexTypeEntry::lookupName() const { return m_lookupName.isEmpty() ? targetLangName() : m_lookupName; } QString ComplexTypeEntry::targetLangApiName() const { return strings_jobject; } QString ContainerTypeEntry::typeName() const { switch(m_type) { case LinkedListContainer: return QLatin1String("linked-list"); case ListContainer: return QLatin1String("list"); case StringListContainer: return QLatin1String("string-list"); case VectorContainer: return QLatin1String("vector"); case StackContainer: return QLatin1String("stack"); case QueueContainer: return QLatin1String("queue"); case SetContainer: return QLatin1String("set"); case MapContainer: return QLatin1String("map"); case MultiMapContainer: return QLatin1String("multi-map"); case HashContainer: return QLatin1String("hash"); case MultiHashContainer: return QLatin1String("multi-hash"); case PairContainer: return QLatin1String("pair"); case NoContainer: default: return QLatin1String("?"); } } static const QSet &primitiveCppTypes() { static QSet result; if (result.isEmpty()) { static const char *cppTypes[] = { "bool", "char", "double", "float", "int", "long", "long long", "short", "wchar_t" }; for (const char *cppType : cppTypes) result.insert(QLatin1String(cppType)); } return result; } void TypeEntry::setInclude(const Include &inc) { // This is a workaround for preventing double inclusion of the QSharedPointer implementation // header, which does not use header guards. In the previous parser this was not a problem // because the Q_QDOC define was set, and the implementation header was never included. if (inc.name().endsWith(QLatin1String("qsharedpointer_impl.h"))) { QString path = inc.name(); path.remove(QLatin1String("_impl")); m_include = Include(inc.type(), path); } else { m_include = inc; } } bool TypeEntry::isCppPrimitive() const { if (!isPrimitive()) return false; if (m_type == VoidType) return true; const PrimitiveTypeEntry *referencedType = static_cast(this)->basicReferencedTypeEntry(); const QString &typeName = referencedType ? referencedType->name() : m_name; return typeName.contains(QLatin1Char(' ')) || primitiveCppTypes().contains(typeName); } TypeEntry::TypeEntry(const QString &name, TypeEntry::Type t, const QVersionNumber &vr) : m_name(name), m_type(t), m_version(vr) { } TypeEntry::~TypeEntry() { delete m_customConversion; } bool TypeEntry::hasCustomConversion() const { return m_customConversion != nullptr; } void TypeEntry::setCustomConversion(CustomConversion* customConversion) { m_customConversion = customConversion; } CustomConversion* TypeEntry::customConversion() const { return m_customConversion; } TypeEntry *TypeEntry::clone() const { return new TypeEntry(*this); } // Take over parameters relevant for typedefs void TypeEntry::useAsTypedef(const TypeEntry *source) { m_name = source->m_name; m_targetLangPackage = source->m_targetLangPackage; m_codeGeneration = source->m_codeGeneration; m_version = source->m_version; } TypeEntry::TypeEntry(const TypeEntry &) = default; TypeSystemTypeEntry::TypeSystemTypeEntry(const QString &name, const QVersionNumber &vr) : TypeEntry(name, TypeSystemType, vr) { } TypeEntry *TypeSystemTypeEntry::clone() const { return new TypeSystemTypeEntry(*this); } TypeSystemTypeEntry::TypeSystemTypeEntry(const TypeSystemTypeEntry &) = default; VoidTypeEntry::VoidTypeEntry() : TypeEntry(QLatin1String("void"), VoidType, QVersionNumber(0, 0)) { } TypeEntry *VoidTypeEntry::clone() const { return new VoidTypeEntry(*this); } VoidTypeEntry::VoidTypeEntry(const VoidTypeEntry &) = default; VarargsTypeEntry::VarargsTypeEntry() : TypeEntry(QLatin1String("..."), VarargsType, QVersionNumber(0, 0)) { } TypeEntry *VarargsTypeEntry::clone() const { return new VarargsTypeEntry(*this); } VarargsTypeEntry::VarargsTypeEntry(const VarargsTypeEntry &) = default; TemplateArgumentEntry::TemplateArgumentEntry(const QString &name, const QVersionNumber &vr) : TypeEntry(name, TemplateArgumentType, vr) { } TypeEntry *TemplateArgumentEntry::clone() const { return new TemplateArgumentEntry(*this); } TemplateArgumentEntry::TemplateArgumentEntry(const TemplateArgumentEntry &) = default; ArrayTypeEntry::ArrayTypeEntry(const TypeEntry *nested_type, const QVersionNumber &vr) : TypeEntry(QLatin1String("Array"), ArrayType, vr), m_nestedType(nested_type) { Q_ASSERT(m_nestedType); } QString ArrayTypeEntry::targetLangName() const { return m_nestedType->targetLangName() + QLatin1String("[]"); } QString ArrayTypeEntry::targetLangApiName() const { return m_nestedType->isPrimitive() ? m_nestedType->targetLangApiName() + QLatin1String("Array") : QLatin1String("jobjectArray"); } TypeEntry *ArrayTypeEntry::clone() const { return new ArrayTypeEntry(*this); } ArrayTypeEntry::ArrayTypeEntry(const ArrayTypeEntry &) = default; EnumTypeEntry::EnumTypeEntry(const QString &nspace, const QString &enumName, const QVersionNumber &vr) : TypeEntry(nspace.isEmpty() ? enumName : nspace + QLatin1String("::") + enumName, EnumType, vr), m_qualifier(nspace), m_targetLangName(enumName) { } QString EnumTypeEntry::targetLangName() const { return m_targetLangName; } EnumValueTypeEntry::EnumValueTypeEntry(const QString &name, const QString &value, const EnumTypeEntry *enclosingEnum, const QVersionNumber &vr) : TypeEntry(name, TypeEntry::EnumValue, vr), m_value(value), m_enclosingEnum(enclosingEnum) { } TypeEntry *EnumValueTypeEntry::clone() const { return new EnumValueTypeEntry(*this); } EnumValueTypeEntry::EnumValueTypeEntry(const EnumValueTypeEntry &) = default; FlagsTypeEntry::FlagsTypeEntry(const QString &name, const QVersionNumber &vr) : TypeEntry(name, FlagsType, vr) { } /* A typedef entry allows for specifying template specializations in the * typesystem XML file. */ TypedefEntry::TypedefEntry(const QString &name, const QString &sourceType, const QVersionNumber &vr) : ComplexTypeEntry(name, TypedefType, vr), m_sourceType(sourceType) { } TypeEntry *TypedefEntry::clone() const { return new TypedefEntry(*this); } TypedefEntry::TypedefEntry(const TypedefEntry &) = default; ContainerTypeEntry::ContainerTypeEntry(const QString &name, Type type, const QVersionNumber &vr) : ComplexTypeEntry(name, ContainerType, vr), m_type(type) { setCodeGeneration(GenerateForSubclass); } SmartPointerTypeEntry::SmartPointerTypeEntry(const QString &name, const QString &getterName, const QString &smartPointerType, const QString &refCountMethodName, const QVersionNumber &vr) : ComplexTypeEntry(name, SmartPointerType, vr), m_getterName(getterName), m_smartPointerType(smartPointerType), m_refCountMethodName(refCountMethodName) { } TypeEntry *SmartPointerTypeEntry::clone() const { return new SmartPointerTypeEntry(*this); } SmartPointerTypeEntry::SmartPointerTypeEntry(const SmartPointerTypeEntry &) = default; NamespaceTypeEntry::NamespaceTypeEntry(const QString &name, const QVersionNumber &vr) : ComplexTypeEntry(name, NamespaceType, vr) { } TypeEntry *NamespaceTypeEntry::clone() const { return new NamespaceTypeEntry(*this); } void NamespaceTypeEntry::setFilePattern(const QRegularExpression &r) { m_filePattern = r; m_hasPattern = !m_filePattern.pattern().isEmpty(); if (m_hasPattern) m_filePattern.optimize(); } NamespaceTypeEntry::NamespaceTypeEntry(const NamespaceTypeEntry &) = default; bool NamespaceTypeEntry::matchesFile(const QString &needle) const { return m_filePattern.match(needle).hasMatch(); } ValueTypeEntry::ValueTypeEntry(const QString &name, const QVersionNumber &vr) : ComplexTypeEntry(name, BasicValueType, vr) { } bool ValueTypeEntry::isValue() const { return true; } bool ValueTypeEntry::isNativeIdBased() const { return true; } TypeEntry *ValueTypeEntry::clone() const { return new ValueTypeEntry(*this); } ValueTypeEntry::ValueTypeEntry(const ValueTypeEntry &) = default; ValueTypeEntry::ValueTypeEntry(const QString &name, Type t, const QVersionNumber &vr) : ComplexTypeEntry(name, t, vr) { } struct CustomConversion::CustomConversionPrivate { CustomConversionPrivate(const TypeEntry* ownerType) : ownerType(ownerType), replaceOriginalTargetToNativeConversions(false) { } const TypeEntry* ownerType; QString nativeToTargetConversion; bool replaceOriginalTargetToNativeConversions; TargetToNativeConversions targetToNativeConversions; }; struct CustomConversion::TargetToNativeConversion::TargetToNativeConversionPrivate { TargetToNativeConversionPrivate() : sourceType(nullptr) { } const TypeEntry* sourceType; QString sourceTypeName; QString sourceTypeCheck; QString conversion; }; CustomConversion::CustomConversion(TypeEntry* ownerType) { m_d = new CustomConversionPrivate(ownerType); if (ownerType) ownerType->setCustomConversion(this); } CustomConversion::~CustomConversion() { qDeleteAll(m_d->targetToNativeConversions); delete m_d; } const TypeEntry* CustomConversion::ownerType() const { return m_d->ownerType; } QString CustomConversion::nativeToTargetConversion() const { return m_d->nativeToTargetConversion; } void CustomConversion::setNativeToTargetConversion(const QString& nativeToTargetConversion) { m_d->nativeToTargetConversion = nativeToTargetConversion; } bool CustomConversion::replaceOriginalTargetToNativeConversions() const { return m_d->replaceOriginalTargetToNativeConversions; } void CustomConversion::setReplaceOriginalTargetToNativeConversions(bool replaceOriginalTargetToNativeConversions) { m_d->replaceOriginalTargetToNativeConversions = replaceOriginalTargetToNativeConversions; } bool CustomConversion::hasTargetToNativeConversions() const { return !(m_d->targetToNativeConversions.isEmpty()); } CustomConversion::TargetToNativeConversions& CustomConversion::targetToNativeConversions() { return m_d->targetToNativeConversions; } const CustomConversion::TargetToNativeConversions& CustomConversion::targetToNativeConversions() const { return m_d->targetToNativeConversions; } void CustomConversion::addTargetToNativeConversion(const QString& sourceTypeName, const QString& sourceTypeCheck, const QString& conversion) { m_d->targetToNativeConversions.append(new TargetToNativeConversion(sourceTypeName, sourceTypeCheck, conversion)); } CustomConversion::TargetToNativeConversion::TargetToNativeConversion(const QString& sourceTypeName, const QString& sourceTypeCheck, const QString& conversion) { m_d = new TargetToNativeConversionPrivate; m_d->sourceTypeName = sourceTypeName; m_d->sourceTypeCheck = sourceTypeCheck; m_d->conversion = conversion; } CustomConversion::TargetToNativeConversion::~TargetToNativeConversion() { delete m_d; } const TypeEntry* CustomConversion::TargetToNativeConversion::sourceType() const { return m_d->sourceType; } void CustomConversion::TargetToNativeConversion::setSourceType(const TypeEntry* sourceType) { m_d->sourceType = sourceType; } bool CustomConversion::TargetToNativeConversion::isCustomType() const { return !(m_d->sourceType); } QString CustomConversion::TargetToNativeConversion::sourceTypeName() const { return m_d->sourceTypeName; } QString CustomConversion::TargetToNativeConversion::sourceTypeCheck() const { return m_d->sourceTypeCheck; } QString CustomConversion::TargetToNativeConversion::conversion() const { return m_d->conversion; } void CustomConversion::TargetToNativeConversion::setConversion(const QString& conversion) { m_d->conversion = conversion; } InterfaceTypeEntry::InterfaceTypeEntry(const QString &name, const QVersionNumber &vr) : ComplexTypeEntry(name, InterfaceType, vr) { } bool InterfaceTypeEntry::isNativeIdBased() const { return true; } QString InterfaceTypeEntry::qualifiedCppName() const { const int len = ComplexTypeEntry::qualifiedCppName().length() - interfaceName(QString()).length(); return ComplexTypeEntry::qualifiedCppName().left(len); } TypeEntry *InterfaceTypeEntry::clone() const { return new InterfaceTypeEntry(*this); } InterfaceTypeEntry::InterfaceTypeEntry(const InterfaceTypeEntry &) = default; FunctionTypeEntry::FunctionTypeEntry(const QString &name, const QString &signature, const QVersionNumber &vr) : TypeEntry(name, FunctionType, vr) { addSignature(signature); } TypeEntry *FunctionTypeEntry::clone() const { return new FunctionTypeEntry(*this); } FunctionTypeEntry::FunctionTypeEntry(const FunctionTypeEntry &) = default; ObjectTypeEntry::ObjectTypeEntry(const QString &name, const QVersionNumber &vr) : ComplexTypeEntry(name, ObjectType, vr) { } InterfaceTypeEntry *ObjectTypeEntry::designatedInterface() const { return m_interface; } bool ObjectTypeEntry::isNativeIdBased() const { return true; } TypeEntry *ObjectTypeEntry::clone() const { return new ObjectTypeEntry(*this); } ObjectTypeEntry::ObjectTypeEntry(const ObjectTypeEntry &) = default;