/* * Copyright (C) 2007 Kevin Krammer * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ // TQt includes #include #include #include #include // local includes #include "classgen.h" #include "methodgen.h" class Set : public TQMap { public: void insertString(const TQString& key) { insert(key, true); } void removeString(const TQString& key) { erase(key); } void insertStringList(const TQStringList& list) { TQStringList::const_iterator it = list.begin(); TQStringList::const_iterator endIt = list.end(); for (; it != endIt; ++it) { insert(*it, true); } } }; static void writeFileHeader(TQTextStream& stream) { stream << "// File autogenerated" << endl; stream << endl; } static void writeFileFooter(TQTextStream& stream) { stream << "// End of File" << endl; stream << endl; } static void openIncludeGuard(const TQString& className, TQTextStream& stream) { stream << "#if !defined(" << className.upper() << "_H_INCLUDED)" << endl; stream << "#define " << className.upper() << "_H_INCLUDED" << endl; stream << endl; } static void closeIncludeGuard(const TQString& className, TQTextStream& stream) { stream << "#endif //" << className.upper() << "_H_INCLUDED" << endl; stream << endl; } static void openNamespaces(const TQStringList& namespaces, TQTextStream& stream) { TQStringList::const_iterator it = namespaces.begin(); TQStringList::const_iterator endIt = namespaces.end(); for (; it != endIt; ++it) { stream << "namespace " << *it << endl; stream << "{" << endl; } stream << endl; } static void closeNamespaces(const TQStringList& namespaces, TQTextStream& stream) { TQStringList::const_iterator it = namespaces.end(); TQStringList::const_iterator endIt = namespaces.end(); for (--it; it != endIt; --it) { stream << "}; // namespace " << *it << endl; stream << endl; } } static void writeIncludes(const TQString& description, const TQStringList& includes, TQTextStream& stream) { if (includes.isEmpty()) return; stream << "// " << description << " includes" << endl; TQStringList::const_iterator it = includes.begin(); TQStringList::const_iterator endIt = includes.end(); for (;it != endIt; ++it) { stream << "#include " << *it << endl; } stream << endl; } static void extractHeaderIncludes(const Method& method, TQMap& includes) { TQValueList::const_iterator it = method.arguments.begin(); TQValueList::const_iterator endIt = method.arguments.end(); for (; it != endIt; ++it) { if ((*it).headerIncludes.isEmpty()) continue; TQMap::const_iterator mapIt = (*it).headerIncludes.begin(); TQMap::const_iterator mapEndIt = (*it).headerIncludes.end(); for (; mapIt != mapEndIt; ++mapIt) { includes[mapIt.key()].insertStringList(mapIt.data()); } } } static void extractForwardDeclarations(const Method& method, Set& forwards) { TQValueList::const_iterator it = method.arguments.begin(); TQValueList::const_iterator endIt = method.arguments.end(); for (; it != endIt; ++it) { if ((*it).forwardDeclarations.isEmpty()) continue; forwards.insertStringList((*it).forwardDeclarations); } } static void writeHeaderIncludes(const Class& classData, Class::Role role, TQTextStream& stream) { TQMap includes; Set forwards; TQValueList::const_iterator it = classData.methods.begin(); TQValueList::const_iterator endIt = classData.methods.end(); for (; it != endIt; ++it) { if ((*it).arguments.isEmpty()) continue; extractHeaderIncludes(*it, includes); extractForwardDeclarations(*it, forwards); } it = classData.msignals.begin(); endIt = classData.msignals.end(); for (; it != endIt; ++it) { if ((*it).arguments.isEmpty()) continue; extractHeaderIncludes(*it, includes); extractForwardDeclarations(*it, forwards); } TQValueList::const_iterator propertyIt = classData.properties.begin(); TQValueList::const_iterator propertyEndIt = classData.properties.end(); for (; propertyIt != propertyEndIt; ++propertyIt) { if (!(*propertyIt).headerIncludes.isEmpty()) { TQMap::const_iterator mapIt = (*propertyIt).headerIncludes.begin(); TQMap::const_iterator mapEndIt = (*propertyIt).headerIncludes.end(); for (; mapIt != mapEndIt; ++mapIt) { includes[mapIt.key()].insertStringList(mapIt.data()); } } if (!(*propertyIt).forwardDeclarations.isEmpty()) { forwards.insertStringList((*propertyIt).forwardDeclarations); } } switch (role) { case Class::Interface: includes["tqdbus"].insertString(""); forwards.insertString("class TQT_DBusError"); forwards.insertString("class TQDomElement"); if (!classData.msignals.isEmpty()) forwards.insertString("class TQString"); if (!classData.asyncMethods.isEmpty()) { includes["TQt"].insertString(""); forwards.erase("template class TQMap"); includes["tqdbus"].insertString(""); forwards.erase("class TQT_DBusMessage"); } break; case Class::Proxy: includes["TQt"].insertString(""); forwards.insertString("class TQT_DBusConnection"); forwards.insertString("class TQT_DBusError"); forwards.insertString("class TQT_DBusMessage"); forwards.insertString("class TQT_DBusProxy"); forwards.insertString("class TQString"); if (!classData.properties.isEmpty()) forwards.insertString("class TQT_DBusVariant"); if (!classData.asyncMethods.isEmpty()) { includes["TQt"].insertString(""); forwards.erase("template class TQMap"); } break; case Class::Node: includes["tqdbus"].insertString(""); forwards.insertString("class TQT_DBusConnection"); forwards.insertString("class TQString"); break; } if (!includes["TQt"].isEmpty()) writeIncludes("TQt", includes["TQt"].keys(), stream); if (!includes["tqdbus"].isEmpty()) writeIncludes("TQt D-Bus", includes["tqdbus"].keys(), stream); if (!includes["local"].isEmpty()) writeIncludes("local", includes["local"].keys(), stream); stream << "// forward declarations" << endl; Set::const_iterator setIt = forwards.begin(); Set::const_iterator setEndIt = forwards.end(); for (; setIt != setEndIt; ++setIt) { stream << setIt.key() << ";" << endl; } stream << endl; } static void extractSourceIncludes(const Method& method, TQMap& includes) { TQValueList::const_iterator it = method.arguments.begin(); TQValueList::const_iterator endIt = method.arguments.end(); for (; it != endIt; ++it) { if ((*it).sourceIncludes.isEmpty()) continue; TQMap::const_iterator mapIt = (*it).sourceIncludes.begin(); TQMap::const_iterator mapEndIt = (*it).sourceIncludes.end(); for (; mapIt != mapEndIt; ++mapIt) { includes[mapIt.key()].insertStringList(mapIt.data()); } } } static void writeSourceIncludes(const Class& classData, Class::Role role, TQTextStream& stream) { TQMap includes; TQValueList::const_iterator it = classData.methods.begin(); TQValueList::const_iterator endIt = classData.methods.end(); for (; it != endIt; ++it) { if ((*it).arguments.isEmpty()) continue; extractSourceIncludes(*it, includes); } it = classData.msignals.begin(); endIt = classData.msignals.end(); for (; it != endIt; ++it) { if ((*it).arguments.isEmpty()) continue; extractSourceIncludes(*it, includes); } TQValueList::const_iterator propertyIt = classData.properties.begin(); TQValueList::const_iterator propertyEndIt = classData.properties.end(); for (; propertyIt != propertyEndIt; ++propertyIt) { if ((*propertyIt).sourceIncludes.isEmpty()) continue; TQMap::const_iterator mapIt = (*propertyIt).sourceIncludes.begin(); TQMap::const_iterator mapEndIt = (*propertyIt).sourceIncludes.end(); for (; mapIt != mapEndIt; ++mapIt) { includes[mapIt.key()].insertStringList(mapIt.data()); } } switch (role) { case Class::Interface: includes["TQt"].insertString(""); includes["tqdbus"].insertString(""); includes["tqdbus"].insertString(""); break; case Class::Proxy: includes["tqdbus"].insertString(""); includes["tqdbus"].insertString(""); includes["tqdbus"].insertString(""); if (!classData.properties.isEmpty()) { includes["tqdbus"].insertString(""); includes["tqdbus"].insertString(""); } break; case Class::Node: includes["TQt"].insertString(""); includes["TQt"].insertString(""); includes["tqdbus"].insertString(""); includes["tqdbus"].insertString(""); break; } if (!includes["TQt"].isEmpty()) writeIncludes("TQt", includes["TQt"].keys(), stream); if (!includes["tqdbus"].isEmpty()) writeIncludes("TQt D-Bus", includes["tqdbus"].keys(), stream); if (!includes["local"].isEmpty()) writeIncludes("local", includes["local"].keys(), stream); stream << endl; } static void writeInterfaceIncludes(const TQValueList interfaces, TQTextStream& stream) { stream << "// interface classes includes" << endl; TQValueList::const_iterator it = interfaces.begin(); TQValueList::const_iterator endIt = interfaces.end(); for (; it != endIt; ++it) { stream << "#include \"" << (*it).name.lower() << ".h\"" << endl; } stream << "#include \"introspectableinterface.h\"" << endl; stream << endl; } static void openClassDeclaration(const Class& classData, Class::Role role, TQTextStream& stream) { switch (role) { case Class::Interface: stream << "class " << classData.name << " : public TQT_DBusObjectBase" << endl; stream << "{" << endl; stream << "public:" << endl; stream << " virtual ~" << classData.name << "() {}" << endl; stream << endl; stream << " static void buildIntrospectionData(TQDomElement& interfaceElement);" << endl; break; case Class::Proxy: stream << "class " << classData.name << " : public TQObject" << endl; stream << "{" << endl; stream << " Q_OBJECT" << endl; stream << " " << endl; stream << "public:" << endl; stream << " " << classData.name << "(const TQString& service, const TQString& path, TQObject* parent = 0, const char* name = 0);" << endl; stream << endl; stream << " virtual ~" << classData.name << "();" << endl; stream << endl; stream << " void setConnection(const TQT_DBusConnection& connection);" << endl; break; case Class::Node: stream << "class " << classData.name << " : public TQT_DBusObjectBase" << endl; stream << "{" << endl; stream << "public:" << endl; stream << " " << classData.name << "();" << endl; stream << endl; stream << " virtual ~" << classData.name << "();" << endl; stream << endl; stream << " bool registerObject(const TQT_DBusConnection& connection, " << "const TQString& path);" << endl; stream << endl; stream << " void unregisterObject();" << endl; stream << endl; stream << "protected:" << endl; stream << " virtual TQT_DBusObjectBase* createInterface(" << "const TQString& interfaceName) = 0;" << endl; stream << endl; stream << "protected: // usually no need to reimplement" << endl; stream << " virtual bool handleMethodCall(const TQT_DBusMessage& message);" << endl; stream << endl; stream << "private:" << endl; stream << " class Private;" << endl; stream << " Private* m_private;" << endl; break; } stream << endl; } static void closeClassDeclaration(const Class& classData, Class::Role role, TQTextStream& stream) { switch (role) { case Class::Interface: break; case Class::Proxy: stream << "private: // Hiding copy constructor and assignment operator" << endl; stream << " " << classData.name << "(const " << classData.name << "&);" << endl; stream << " " << classData.name << "& operator=(const " << classData.name << "&);" << endl; break; case Class::Node: stream << "private: // Hiding copy constructor and assignment operator" << endl; stream << " " << classData.name << "(const " << classData.name << "&);" << endl; stream << " " << classData.name << "& operator=(const " << classData.name << "&);" << endl; break; } stream << "}; // class " << classData.name << endl; stream << endl; } static void writeMethodDeclarations(const Class& classData, Class::Role role, TQTextStream& stream) { if (role == Class::Interface && !classData.asyncReplyMethods.isEmpty()) { stream << "public:" << endl; TQValueList::const_iterator it = classData.asyncReplyMethods.begin(); TQValueList::const_iterator endIt = classData.asyncReplyMethods.end(); for (; it != endIt; ++it) { Method method = *it; method.name += "AsyncReply"; stream << " virtual void "; MethodGenerator::writeMethodDeclaration(method, false, false, stream); stream << " virtual void " << (*it).name << "AsyncError(int asyncCallId, const TQT_DBusError& error);" << endl; stream << endl; } } if (!classData.methods.isEmpty() || !classData.asyncMethods.isEmpty()) { bool pureVirtual = true; switch (role) { case Class::Interface: pureVirtual = true; stream << "protected:" << endl; break; case Class::Proxy: pureVirtual = false; stream << "public:" << endl; break; case Class::Node: // no variable methods break; } TQValueList::const_iterator it = classData.methods.begin(); TQValueList::const_iterator endIt = classData.methods.end(); for (; it != endIt; ++it) { if ((*it).async) continue; stream << " virtual bool "; MethodGenerator::writeMethodDeclaration(*it, pureVirtual, true, stream); } it = classData.asyncMethods.begin(); endIt = classData.asyncMethods.end(); for (; it != endIt; ++it) { Method method = *it; method.name += "Async"; switch (role) { case Class::Interface: stream << " virtual void "; MethodGenerator::writeMethodDeclaration(method, pureVirtual, false, stream); break; case Class::Proxy: stream << " virtual bool "; MethodGenerator::writeMethodDeclaration(method, pureVirtual, true, stream); break; case Class::Node: // no async methods break; } } } if (!classData.properties.isEmpty()) { bool pureVirtual = true; bool skip = false; switch (role) { case Class::Interface: qWarning("Properties not yet supported for interfaces"); skip = true; pureVirtual = true; break; case Class::Proxy: pureVirtual = false; stream << "public:" << endl; stream << " virtual void setDBusProperty(const TQString& name," << " const TQT_DBusVariant& variant, TQT_DBusError& error);" << endl; stream << " virtual TQT_DBusVariant getDBusProperty(const TQString& name, TQT_DBusError& error) const;" << endl; stream << endl; break; case Class::Node: // no node properties skip = true; break; } if (!skip) { TQValueList::const_iterator it = classData.properties.begin(); TQValueList::const_iterator endIt = classData.properties.end(); for (; it != endIt; ++it) { MethodGenerator::writePropertyDeclaration(*it, pureVirtual, stream); } } } switch (role) { case Class::Interface: if (!classData.methods.isEmpty() || !classData.asyncMethods.isEmpty()) { stream << "protected: // implement sending replies" << endl; stream << " virtual void handleMethodReply(const TQT_DBusMessage& reply) = 0;" << endl; stream << endl; stream << "protected: // usually no need to reimplement" << endl; stream << " virtual bool handleMethodCall(const TQT_DBusMessage& message);" << endl; } else { stream << "protected: // no methods to handle" << endl; stream << " virtual bool handleMethodCall(const TQT_DBusMessage&) { return false; }" << endl; } break; case Class::Proxy: { if (!classData.msignals.isEmpty()) { stream << "protected slots: // usually no need to reimplement" << endl; stream << " virtual void slotHandleDBusSignal(const TQT_DBusMessage& message);" << endl; stream << endl; } if (!classData.asyncReplySignals.isEmpty()) { if (classData.msignals.isEmpty()) { stream << "protected slots: // usually no need to reimplement" << endl; } stream << " virtual void slotHandleAsyncReply(int id, const TQT_DBusMessage& message);" << endl; stream << endl; } stream << "protected:" << endl; stream << " TQT_DBusProxy* m_baseProxy;" << endl; if (!classData.asyncMethods.isEmpty()) { stream << endl; stream << " TQMap m_asyncCalls;" << endl; } break; } case Class::Node: // not variable methods break; } stream << endl; } static void writeSignalDeclarations(const Class& classData, Class::Role role, TQTextStream& stream) { if (classData.msignals.isEmpty() && classData.asyncReplySignals.isEmpty()) return; TQString prefix; switch (role) { case Class::Interface: stream << "protected: // implement sending signals" << endl; stream << " virtual bool handleSignalSend(const TQT_DBusMessage& reply) = 0;" << endl; stream << " virtual TQString objectPath() const = 0;" << endl; stream << endl; stream << "protected: // for sending D-Bus signals" << endl; prefix = " virtual bool emit"; break; case Class::Proxy: stream << "signals:" << endl; prefix = " void "; break; case Class::Node: // no signals break; } TQValueList::const_iterator it = classData.msignals.begin(); TQValueList::const_iterator endIt = classData.msignals.end(); for (; it != endIt; ++it) { stream << prefix; MethodGenerator::writeMethodDeclaration(*it, false, false, stream); } it = classData.asyncReplySignals.begin(); endIt = classData.asyncReplySignals.end(); for (; it != endIt; ++it) { stream << prefix; Method signal = *it; signal.name += "AsyncReply"; MethodGenerator::writeMethodDeclaration(signal, false, false, stream); } stream << endl; } static void writeSignalEmitters(const Class& classData, TQTextStream& stream) { if (classData.msignals.isEmpty()) return; TQValueList::const_iterator it = classData.msignals.begin(); TQValueList::const_iterator endIt = classData.msignals.end(); for (; it != endIt; ++it) { MethodGenerator::writeSignalEmitter(classData, *it, stream); } stream << endl; } static void writeMethodCallDeclarations(const Class& classData, TQTextStream& stream) { TQValueList::const_iterator it = classData.methods.begin(); TQValueList::const_iterator endIt = classData.methods.end(); for (; it != endIt; ++it) { stream << " "; MethodGenerator::writeMethodCallDeclaration(*it, stream); } if (!classData.asyncReplyMethods.isEmpty()) { stream << "protected:" << endl; stream << " TQMap m_asyncCalls;" << endl; stream << endl; } } static void writeInterfaceAsyncReplyHandlers(const Class& classData, TQTextStream& stream) { if (classData.asyncReplyMethods.isEmpty()) return; TQValueList::const_iterator it = classData.asyncReplyMethods.begin(); TQValueList::const_iterator endIt = classData.asyncReplyMethods.end(); for (; it != endIt; ++it) { MethodGenerator::writeInterfaceAsyncReplyHandler(classData, *it, stream); } } static void writeMethodCalls(const Class& classData, TQTextStream& stream) { TQValueList::const_iterator it = classData.methods.begin(); TQValueList::const_iterator endIt = classData.methods.end(); for (; it != endIt; ++it) { if ((*it).async) continue; MethodGenerator::writeMethodCall(classData, *it, stream); } it = classData.asyncMethods.begin(); endIt = classData.asyncMethods.end(); for (; it != endIt; ++it) { MethodGenerator::writeMethodCall(classData, *it, stream); } } static void writeProxyMethods(const Class& classData, TQTextStream& stream) { TQValueList::const_iterator it = classData.methods.begin(); TQValueList::const_iterator endIt = classData.methods.end(); for (; it != endIt; ++it) { if ((*it).async) continue; MethodGenerator::writeProxyMethod(classData.name, *it, stream); } it = classData.asyncMethods.begin(); endIt = classData.asyncMethods.end(); for (; it != endIt; ++it) { MethodGenerator::writeProxyMethod(classData.name, *it, stream); } } static void writeProxyProperties(const Class& classData, TQTextStream& stream) { if (classData.properties.isEmpty()) return; MethodGenerator::writeProxyGenericProperty(classData, stream); TQValueList::const_iterator it = classData.properties.begin(); TQValueList::const_iterator endIt = classData.properties.end(); for (; it != endIt; ++it) { MethodGenerator::writeProxyProperty(classData, *it, stream); } } static void splitAsyncProxyMethods(Class& classData) { // create the async identifier Argument idArgMethod; idArgMethod.name = "asyncCallId"; idArgMethod.signature = "int"; idArgMethod.isPrimitive = true; idArgMethod.direction = Argument::Out; Argument idArgSignal = idArgMethod; idArgSignal.direction = Argument::In; TQValueList::iterator it = classData.methods.begin(); TQValueList::iterator endIt = classData.methods.end(); for (; it != endIt; ++it) { if (!(*it).async) continue; Method method = *it; TQValueList methodArgs; TQValueList signalArgs; // add id argument methodArgs << idArgMethod; signalArgs << idArgSignal; // split in/out arguments: "in" belong to the method, "out" to the new signal TQValueList::const_iterator argIt = method.arguments.begin(); TQValueList::const_iterator argEndIt = method.arguments.end(); for (; argIt != argEndIt; ++argIt) { if ((*argIt).direction == Argument::Out) { // signal parameters are "out" but have "in" signature, // e.g. "const T&" Argument arg = *argIt; arg.direction = Argument::In; signalArgs << arg; } else methodArgs << *argIt; } // change method method.arguments = methodArgs; classData.asyncMethods << method; // create "callback" signal Method signal = method; signal.arguments = signalArgs; classData.asyncReplySignals << signal; } } static void splitAsyncInterfaceMethods(Class& classData) { // create the async identifier Argument idArgMethod; idArgMethod.name = "asyncCallId"; idArgMethod.signature = "int"; idArgMethod.isPrimitive = true; idArgMethod.direction = Argument::In; Argument idArgReply = idArgMethod; TQValueList::iterator it = classData.methods.begin(); TQValueList::iterator endIt = classData.methods.end(); for (; it != endIt; ++it) { if (!(*it).async) continue; Method method = *it; TQValueList methodArgs; TQValueList replyArgs; // add id argument methodArgs << idArgMethod; replyArgs << idArgReply; // split in/out arguments: "in" belong to the call, "out" to the reply TQValueList::const_iterator argIt = method.arguments.begin(); TQValueList::const_iterator argEndIt = method.arguments.end(); for (; argIt != argEndIt; ++argIt) { if ((*argIt).direction == Argument::Out) { // reply parameters are "out" for the service but "in" for // the reply handler Argument arg = *argIt; arg.direction = Argument::In; replyArgs << arg; } else methodArgs << *argIt; } // change method method.arguments = methodArgs; classData.asyncMethods << method; // create reply handler Method reply = method; reply.arguments = replyArgs; classData.asyncReplyMethods << reply; } } bool ClassGenerator::initStreams(const TQString& baseName, TQTextStream& headerStream, TQTextStream& sourceStream) { TQFile* headerFile = new TQFile(baseName + ".h"); TQFile* sourceFile = new TQFile(baseName + ".cpp"); if (!headerFile->open(IO_WriteOnly) || !sourceFile->open(IO_WriteOnly)) { delete headerFile; delete sourceFile; return false; } headerStream.setDevice(TQT_TQIODEVICE(headerFile)); sourceStream.setDevice(TQT_TQIODEVICE(sourceFile)); // create header writeFileHeader(headerStream); openIncludeGuard(baseName, headerStream); // create source writeFileHeader(sourceStream); sourceStream << "// declaration include" << endl; sourceStream << "#include \"" << baseName << ".h\"" << endl; sourceStream << endl; return true; } bool ClassGenerator::finishStreams(const TQString& baseName, TQTextStream& headerStream, TQTextStream& sourceStream) { closeIncludeGuard(baseName, headerStream); writeFileFooter(headerStream); writeFileFooter(sourceStream); TQIODevice* device = headerStream.device(); headerStream.unsetDevice(); delete device; device = sourceStream.device(); sourceStream.unsetDevice(); delete device; return true; } bool ClassGenerator::extractClass(const TQDomElement& interfaceElement, Class& classData) { qDebug("ClassGenerator: processing interface '%s'", interfaceElement.attribute("name").latin1()); classData.dbusName = interfaceElement.attribute("name"); TQStringList nameParts = TQStringList::split('.', classData.dbusName); if (nameParts.count() < 2) return false; classData.name = nameParts.back(); nameParts.pop_back(); classData.namespaces = nameParts; return MethodGenerator::extractMethods(interfaceElement, classData); } bool ClassGenerator::generateInterface(const Class& classData, TQTextStream& headerStream, TQTextStream& sourceStream) { Class classDataCopy = classData; splitAsyncInterfaceMethods(classDataCopy); // create header writeHeaderIncludes(classDataCopy, Class::Interface, headerStream); openNamespaces(classDataCopy.namespaces, headerStream); openClassDeclaration(classDataCopy, Class::Interface, headerStream); writeSignalDeclarations(classDataCopy, Class::Interface, headerStream); writeMethodDeclarations(classDataCopy, Class::Interface, headerStream); writeMethodCallDeclarations(classDataCopy, headerStream); closeClassDeclaration(classDataCopy, Class::Interface, headerStream); closeNamespaces(classDataCopy.namespaces, headerStream); // create source writeSourceIncludes(classDataCopy, Class::Interface, sourceStream); openNamespaces(classDataCopy.namespaces, sourceStream); MethodGenerator::writeIntrospectionDataMethod(classDataCopy, sourceStream); writeSignalEmitters(classDataCopy, sourceStream); writeInterfaceAsyncReplyHandlers(classDataCopy, sourceStream); writeMethodCalls(classDataCopy, sourceStream); MethodGenerator::writeInterfaceMainMethod(classDataCopy, sourceStream); closeNamespaces(classDataCopy.namespaces, sourceStream); return true; } bool ClassGenerator::generateProxy(const Class& classData, TQTextStream& headerStream, TQTextStream& sourceStream) { Class classDataCopy = classData; splitAsyncProxyMethods(classDataCopy); // create header writeHeaderIncludes(classDataCopy, Class::Proxy, headerStream); openNamespaces(classDataCopy.namespaces, headerStream); openClassDeclaration(classDataCopy, Class::Proxy, headerStream); writeSignalDeclarations(classDataCopy, Class::Proxy, headerStream); writeMethodDeclarations(classDataCopy, Class::Proxy, headerStream); closeClassDeclaration(classDataCopy, Class::Proxy, headerStream); closeNamespaces(classDataCopy.namespaces, headerStream); // create source writeSourceIncludes(classDataCopy, Class::Proxy, sourceStream); openNamespaces(classDataCopy.namespaces, sourceStream); MethodGenerator::writeProxyBegin(classDataCopy, sourceStream); writeProxyMethods(classDataCopy, sourceStream); writeProxyProperties(classDataCopy, sourceStream); if (!classDataCopy.msignals.isEmpty()) MethodGenerator::writeSignalHandler(classDataCopy, sourceStream); if (!classDataCopy.asyncReplySignals.isEmpty()) MethodGenerator::writeProxyAsyncReplyHandler(classDataCopy, sourceStream); closeNamespaces(classDataCopy.namespaces, sourceStream); return true; } bool ClassGenerator::generateNode(const Class& classData, const TQValueList& interfaces, TQTextStream& headerStream, TQTextStream& sourceStream) { // create header writeHeaderIncludes(classData, Class::Node, headerStream); openNamespaces(classData.namespaces, headerStream); openClassDeclaration(classData, Class::Node, headerStream); closeClassDeclaration(classData, Class::Node, headerStream); closeNamespaces(classData.namespaces, headerStream); // create source writeSourceIncludes(classData, Class::Node, sourceStream); writeInterfaceIncludes(interfaces, sourceStream); openNamespaces(classData.namespaces, sourceStream); MethodGenerator::writeNodePrivate(classData, sourceStream); MethodGenerator::writeNodeBegin(classData, sourceStream); MethodGenerator::writeNodeMethods(classData, interfaces, sourceStream); closeNamespaces(classData.namespaces, sourceStream); return true; } // End of File