diff generator/cppheadergenerator.cpp @ 1:e78566595089

initial import
author mandel
date Mon, 11 May 2009 16:01:50 +0000
parents
children e747af2e6b46
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/generator/cppheadergenerator.cpp	Mon May 11 16:01:50 2009 +0000
@@ -0,0 +1,312 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Nokia. All rights reserved.
+**
+** This file is part of Qt Jambi.
+**
+** * Commercial Usage
+* Licensees holding valid Qt Commercial licenses may use this file in
+* accordance with the Qt Commercial License Agreement provided with the
+* Software or, alternatively, in accordance with the terms contained in
+* a written agreement between you and Nokia.
+*
+*
+* GNU General Public License Usage
+* Alternatively, this file may be used under the terms of the GNU
+* General Public License versions 2.0 or 3.0 as published by the Free
+* Software Foundation and appearing in the file LICENSE.GPL included in
+* the packaging of this file.  Please review the following information
+* to ensure GNU General Public Licensing requirements will be met:
+* http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+* http://www.gnu.org/copyleft/gpl.html.  In addition, as a special
+* exception, Nokia gives you certain additional rights. These rights
+* are described in the Nokia Qt GPL Exception version 1.2, included in
+* the file GPL_EXCEPTION.txt in this package.
+* 
+* Qt for Windows(R) Licensees
+* As a special exception, Nokia, as the sole copyright holder for Qt
+* Designer, grants users of the Qt/Eclipse Integration plug-in the
+* right for the Qt/Eclipse Integration to link to functionality
+* provided by Qt Designer and its related libraries.
+*
+*
+* If you are unsure which license is appropriate for your use, please
+* contact the sales department at qt-sales@nokia.com.
+
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include "cppheadergenerator.h"
+
+#include <QtCore/QDir>
+
+#include <qdebug.h>
+
+QString CppHeaderGenerator::fileNameForClass(const AbstractMetaClass *java_class) const
+{
+    return QString("%1_shell.h").arg(java_class->name());
+}
+
+void CppHeaderGenerator::writeFieldAccessors(QTextStream &s, const AbstractMetaField *java_field)
+{
+    Q_ASSERT(java_field->isProtected());
+
+    const AbstractMetaFunction *setter = java_field->setter();
+    const AbstractMetaFunction *getter = java_field->getter();
+
+    // qtd2
+    if(notWrappedYet(getter))
+        return;
+
+    if (getter->isModifiedRemoved(TypeSystem::ShellCode))
+        return;
+
+    s << "    ";
+    writeFunctionSignature(s, getter, 0, QString(), Option(ShowStatic));
+    s << ";" << endl;
+
+    // qtd2
+    if(notWrappedYet(setter))
+        return;
+
+    if (!java_field->type()->isConstant()) {
+        if (setter->isModifiedRemoved(TypeSystem::ShellCode))
+            return;
+
+        s << "    ";
+        writeFunctionSignature(s, setter, 0, QString(), Option(ShowStatic));
+        s << ";" << endl;
+    }
+}
+
+void CppHeaderGenerator::writeSignalWrapper(QTextStream &s, const AbstractMetaFunction *signal)
+{
+    s << "    ";
+    writeFunctionSignature(s, signal, 0, signalWrapperPrefix(),
+                           Option(NormalizeAndFixTypeSignature | OriginalName | OriginalTypeDescription | IncludeDefaultExpression));
+    s << ";" << endl;
+}
+
+void CppHeaderGenerator::writeSignalWrappers(QTextStream &s, const AbstractMetaClass *java_class)
+{
+    AbstractMetaFunctionList signal_funcs = signalFunctions(java_class);
+    if (signal_funcs.size() > 0) {
+        s << endl << "public slots:" << endl;
+        foreach (const AbstractMetaFunction *signal, signal_funcs) {
+            writeSignalWrapper(s, signal);
+        }
+    }
+}
+
+void CppHeaderGenerator::writeWrapperClass(QTextStream &s, const AbstractMetaClass *java_class)
+{
+    AbstractMetaFunctionList signal_functions =
+        java_class->queryFunctions(AbstractMetaClass::Signals | AbstractMetaClass::Visible | AbstractMetaClass::NotRemovedFromTargetLang);
+    if (signal_functions.size() == 0)
+        return ;
+
+    s << "class QtJambi_SignalWrapper_" << java_class->name() << ": public QObject" << endl
+      << "{" << endl
+      << "  Q_OBJECT" << endl;
+    writeSignalWrappers(s, java_class);
+    s << endl << "public:" << endl
+      << "    QtJambiSignalInfo m_signals[" << signal_functions.size() << "];" << endl
+      << "    QtJambiLink *link;" << endl
+      << "};" << endl << endl;
+}
+
+void CppHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *java_class)
+{
+    QString include_block = java_class->name().toUpper() + "_SHELL_H";
+
+    s << "#ifndef " << include_block << endl
+      << "#define " << include_block << endl << endl
+//      << "#include <qtjambi_core.h>" << endl
+      << "#include <QtCore/QHash>" << endl
+      << "#include <QObjectEntity.h>" << endl;
+
+    Include inc = java_class->typeEntry()->include();
+    s << "#include ";
+    if (inc.type == Include::IncludePath)
+        s << "<";
+    else
+        s << "\"";
+    s << inc.name;
+    if (inc.type == Include::IncludePath)
+        s << ">";
+    else
+        s << "\"";
+    s << endl << endl;
+
+    IncludeList list = java_class->typeEntry()->extraIncludes();
+    qSort(list.begin(), list.end());
+    foreach (const Include &inc, list) {
+        if (inc.type == Include::TargetLangImport)
+            continue;
+
+        s << "#include ";
+        if (inc.type == Include::LocalPath)
+            s << "\"";
+        else
+            s << "<";
+
+        s << inc.name;
+
+        if (inc.type == Include::LocalPath)
+            s << "\"";
+        else
+            s << ">";
+
+        s << endl;
+    }
+
+/* qtd    writeForwardDeclareSection(s, java_class);
+
+    writeWrapperClass(s, java_class);
+*/
+    s << endl;
+    QString pro_file_name = java_class->package().replace(".", "_") + "/" + java_class->package().replace(".", "_") + ".pri";
+
+    if (!java_class->generateShellClass()) {
+        s << "#endif" << endl << endl;
+        priGenerator->addHeader(pro_file_name, fileNameForClass(java_class));
+        return ;
+    }
+
+    s << "class " << shellClassName(java_class)
+      << " : public " << java_class->qualifiedCppName();
+    if (java_class->hasVirtualFunctions())
+        s << ", public Qtd_QObjectEntity";
+    s << endl  << "{" << endl;
+
+    if (java_class->isQObject()) {
+      s << "public:" << endl
+        << "  Q_OBJECT_CHECK" << endl;
+//        << "  mutable const QMetaObject *m_meta_object;" << endl;
+
+/*      if (java_class->hasVirtualSlots()) {
+          s << "  mutable QHash<int,int> m_map;" << endl;
+      }
+*/
+      s // << "  const QMetaObject *metaObject() const;" << endl
+//        << "  void *qt_metacast(const char *);" << endl
+//        << "  QT_TR_FUNCTIONS" << endl
+        << "  virtual int qt_metacall(QMetaObject::Call, int, void **);" << endl
+        << "private:" << endl;
+    }
+
+
+    s << "public:" << endl;
+    // constructor
+    foreach (const AbstractMetaFunction *function, java_class->functions()) {
+        if (function->isConstructor() && !function->isPrivate())
+            writeFunction(s, function);
+    }
+
+    s << "    ~" << shellClassName(java_class) << "();" << endl;
+    s << endl;
+
+    // All functions in original class that should be reimplemented in shell class
+    AbstractMetaFunctionList shell_functions = java_class->functionsInShellClass();
+    foreach (const AbstractMetaFunction *function, shell_functions) {
+        if(notWrappedYet(function))
+            continue;
+        writeFunction(s, function);
+    }
+
+    // Public call throughs for protected functions
+    AbstractMetaFunctionList public_overrides = java_class->publicOverrideFunctions();
+    foreach (const AbstractMetaFunction *function, public_overrides) {
+        if(notWrappedYet(function))
+            continue;
+        writePublicFunctionOverride(s, function);
+    }
+
+    // Override all virtual functions to get the decision on static/virtual call
+    AbstractMetaFunctionList virtual_functions = java_class->virtualOverrideFunctions();
+    foreach (const AbstractMetaFunction *function, virtual_functions) {
+        if(notWrappedYet(function))
+            continue;
+
+        writeVirtualFunctionOverride(s, function);
+    }
+
+    // Field accessors
+    foreach (const AbstractMetaField *field, java_class->fields()) {
+        if (field->isProtected())
+            writeFieldAccessors(s, field);
+    }
+/* qtd
+    writeVariablesSection(s, java_class);
+*/
+    writeInjectedCode(s, java_class);
+
+    s  << "};" << endl << endl
+       << "#endif // " << include_block << endl;
+
+    priGenerator->addHeader(pro_file_name, fileNameForClass(java_class));
+}
+
+
+/*!
+    Writes out declarations of virtual C++ functions so that they
+    can be reimplemented from the java side.
+*/
+void CppHeaderGenerator::writeFunction(QTextStream &s, const AbstractMetaFunction *java_function)
+{
+    if (java_function->isModifiedRemoved(TypeSystem::ShellCode))
+        return;
+
+    s << "    ";
+    writeFunctionSignature(s, java_function, 0, QString(), Option(OriginalName | ShowStatic));
+    s << ";" << endl;
+}
+
+void CppHeaderGenerator::writePublicFunctionOverride(QTextStream &s,
+                                                     const AbstractMetaFunction *java_function)
+{
+    s << "    ";
+    writeFunctionSignature(s, java_function, 0, "__public_", Option(EnumAsInts | ShowStatic | UnderscoreSpaces));
+    s << ";" << endl;
+}
+
+
+void CppHeaderGenerator::writeVirtualFunctionOverride(QTextStream &s,
+                                                      const AbstractMetaFunction *java_function)
+{
+    if (java_function->isModifiedRemoved(TypeSystem::NativeCode))
+        return;
+
+    s << "    ";
+    writeFunctionSignature(s, java_function, 0, "__override_", Option(EnumAsInts | ShowStatic | UnderscoreSpaces), QString());
+    s << ";" << endl;
+}
+
+
+void CppHeaderGenerator::writeForwardDeclareSection(QTextStream &s, const AbstractMetaClass *)
+{
+    s << endl
+      << "class QtJambiFunctionTable;" << endl
+      << "class QtJambiLink;" << endl;
+}
+
+
+void CppHeaderGenerator::writeVariablesSection(QTextStream &s, const AbstractMetaClass *)
+{
+    s << endl
+      << "    QtJambiFunctionTable *m_vtable;" << endl
+      << "    QtJambiLink *m_link;" << endl;
+}
+
+void CppHeaderGenerator::writeInjectedCode(QTextStream &s, const AbstractMetaClass *java_class)
+{
+    CodeSnipList code_snips = java_class->typeEntry()->codeSnips();
+    foreach (const CodeSnip &cs, code_snips) {
+        if (cs.language == TypeSystem::ShellDeclaration) {
+            s << cs.code() << endl;
+        }
+    }
+}