diff --git a/generator/abstractmetalang.cpp b/generator/abstractmetalang.cpp index d565e7266..c15d80106 100644 --- a/generator/abstractmetalang.cpp +++ b/generator/abstractmetalang.cpp @@ -1066,7 +1066,7 @@ void AbstractMetaClass::setFunctions(const AbstractMetaFunctionList& functions) bool AbstractMetaClass::hasFieldAccessors() const { for (const AbstractMetaField* field : fields()) { - if (field->getter() || field->setter()) + if (field->isPublic() && (field->getter() || field->setter())) return true; } @@ -1154,8 +1154,10 @@ bool AbstractMetaClass::hasProtectedFunctions() const bool AbstractMetaClass::generateShellClass() const { return typeEntry()->shouldCreateShell() + // require that classes that get a shell have a virtual destructor + // (required for proper working of derived class) && (m_force_shell_class - || (!isFinal() && (hasVirtualFunctions() || hasProtectedFunctions() || hasFieldAccessors()))); + || (!isFinal() && hasVirtualDestructor() && (hasVirtualFunctions() || hasProtectedConstructors()))); } QPropertySpec* AbstractMetaClass::propertySpecForRead(const QString& name) const @@ -1315,6 +1317,11 @@ bool AbstractMetaClass::hasConstructors() const return queryFunctions(Constructors).size() != 0; } +bool AbstractMetaClass::hasProtectedConstructors() const +{ + return queryFunctions(Constructors | WasProtected).size() != 0; +} + void AbstractMetaClass::addDefaultConstructor() { AbstractMetaFunction* f = new AbstractMetaFunction; diff --git a/generator/abstractmetalang.h b/generator/abstractmetalang.h index 6e62499b7..59a2ad321 100644 --- a/generator/abstractmetalang.h +++ b/generator/abstractmetalang.h @@ -697,6 +697,7 @@ class AbstractMetaClass : public AbstractMetaAttributes bool hasSignal(const AbstractMetaFunction* f) const; bool hasConstructors() const; + bool hasProtectedConstructors() const; void addDefaultConstructor(); diff --git a/generator/shellheadergenerator.cpp b/generator/shellheadergenerator.cpp index ce8fb6448..d0ef5a7a7 100644 --- a/generator/shellheadergenerator.cpp +++ b/generator/shellheadergenerator.cpp @@ -135,7 +135,8 @@ void ShellHeaderGenerator::write(QTextStream& s, const AbstractMetaClass* meta_c } // Shell------------------------------------------------------------------- - if (meta_class->generateShellClass() && !ctors.isEmpty()) { + bool generateShell = meta_class->generateShellClass() && !ctors.isEmpty(); + if (generateShell) { AbstractMetaFunctionList virtualsForShell = getVirtualFunctionsForShell(meta_class); @@ -348,12 +349,12 @@ void ShellHeaderGenerator::write(QTextStream& s, const AbstractMetaClass* meta_c } } s << "public Q_SLOTS:" << Qt::endl; - if (meta_class->generateShellClass() || !meta_class->isAbstract()) { + if (generateShell || !meta_class->isAbstract()) { bool copyConstructorSeen = false; bool defaultConstructorSeen = false; for (const AbstractMetaFunction* fun : ctors) { - if (fun->isAbstract() || (!meta_class->generateShellClass() && !fun->isPublic())) { + if (fun->isAbstract() || (!generateShell && !fun->isPublic())) { continue; } @@ -373,8 +374,7 @@ void ShellHeaderGenerator::write(QTextStream& s, const AbstractMetaClass* meta_c if (meta_class->typeEntry()->isValue() && !copyConstructorSeen && defaultConstructorSeen && !meta_class->typeEntry()->hasNoCopy()) { - QString className = - meta_class->generateShellClass() ? shellClassName(meta_class) : meta_class->qualifiedCppName(); + QString className = generateShell ? shellClassName(meta_class) : meta_class->qualifiedCppName(); s << meta_class->qualifiedCppName() << "* new_" << meta_class->name() << "(const " << meta_class->qualifiedCppName() << "& other) {" << Qt::endl; s << className << "* a = new " << className << "();" << Qt::endl; diff --git a/generator/shellimplgenerator.cpp b/generator/shellimplgenerator.cpp index 38d18d3c1..f3d8c3f66 100644 --- a/generator/shellimplgenerator.cpp +++ b/generator/shellimplgenerator.cpp @@ -228,11 +228,11 @@ void ShellImplGenerator::write(QTextStream& s, const AbstractMetaClass* meta_cla } } - if (meta_class->generateShellClass() || !meta_class->isAbstract()) { + if (generateShell || !meta_class->isAbstract()) { // write constructors for (const AbstractMetaFunction* ctor : ctors) { - if (ctor->isAbstract() || (!meta_class->generateShellClass() && !ctor->isPublic())) { + if (ctor->isAbstract() || (!generateShell && !ctor->isPublic())) { continue; } @@ -241,8 +241,7 @@ void ShellImplGenerator::write(QTextStream& s, const AbstractMetaClass* meta_cla writeFunctionSignature(s, ctor, 0, "new_", Option(AddOwnershipTemplates | ShowStatic)); s << Qt::endl; s << "{ " << Qt::endl; - s << "return new " - << (meta_class->generateShellClass() ? shellClassName(meta_class) : meta_class->qualifiedCppName()) << "("; + s << "return new " << (generateShell ? shellClassName(meta_class) : meta_class->qualifiedCppName()) << "("; AbstractMetaArgumentList args = ctor->arguments(); for (int i = 0; i < args.size(); ++i) { if (i > 0) @@ -333,7 +332,6 @@ void ShellImplGenerator::write(QTextStream& s, const AbstractMetaClass* meta_cla } } else { if (fun->wasProtected()) { - //|| (fun->isVirtual() && meta_class->typeEntry()->shouldCreatePromoter())) { s << " ((" << promoterClassName(meta_class) << "*)theWrappedObject)->promoted_"; } else { s << " theWrappedObject->";