summaryrefslogtreecommitdiffstats
path: root/generator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'generator.cpp')
-rw-r--r--generator.cpp205
1 files changed, 205 insertions, 0 deletions
diff --git a/generator.cpp b/generator.cpp
index 343ebc6..3004063 100644
--- a/generator.cpp
+++ b/generator.cpp
@@ -141,3 +141,208 @@ void Generator::replaceTemplateVariables(QString &code, const AbstractMetaFuncti
}
}
+AbstractMetaFunctionList Generator::queryFunctions(const AbstractMetaClass *cppClass, bool allFunctions)
+{
+ AbstractMetaFunctionList result;
+
+ if (allFunctions) {
+ int default_flags = AbstractMetaClass::NormalFunctions | AbstractMetaClass::Visible;
+ default_flags |= cppClass->isInterface() ? 0 : AbstractMetaClass::ClassImplements;
+
+ // Constructors
+ result = cppClass->queryFunctions(AbstractMetaClass::Constructors |
+ default_flags);
+
+ // put enum constructor first to avoid conflict with int contructor
+ result = sortContructor(result);
+
+ // Final functions
+ result += cppClass->queryFunctions(AbstractMetaClass::FinalInTargetLangFunctions |
+ AbstractMetaClass::NonStaticFunctions |
+ default_flags);
+
+ //virtual
+ result += cppClass->queryFunctions(AbstractMetaClass::VirtualInTargetLangFunctions |
+ AbstractMetaClass::NonStaticFunctions |
+ default_flags);
+
+ // Static functions
+ result += cppClass->queryFunctions(AbstractMetaClass::StaticFunctions | default_flags);
+
+ // Empty, private functions, since they aren't caught by the other ones
+ result += cppClass->queryFunctions(AbstractMetaClass::Empty |
+ AbstractMetaClass::Invisible | default_flags);
+ // Signals
+ result += cppClass->queryFunctions(AbstractMetaClass::Signals | default_flags);
+ } else {
+ result = cppClass->functionsInTargetLang();
+ }
+
+ return result;
+}
+
+AbstractMetaFunctionList Generator::filterFunctions(const AbstractMetaClass *cppClass)
+{
+ AbstractMetaFunctionList lst = queryFunctions(cppClass, true);
+ foreach (AbstractMetaFunction *func, lst) {
+ //skip signals
+ if (func->isSignal() ||
+ func->isDestructor() ||
+ (func->isModifiedRemoved() && !func->isAbstract())) {
+ lst.removeOne(func);
+ }
+ }
+
+ //virtual not implemented in current class
+ AbstractMetaFunctionList virtual_lst = cppClass->queryFunctions(AbstractMetaClass::VirtualFunctions);
+ foreach (AbstractMetaFunction *func, virtual_lst) {
+ if ((func->implementingClass() != cppClass) &&
+ !lst.contains(func)) {
+ lst.append(func);
+ }
+ }
+
+ //append global operators
+ foreach (AbstractMetaFunction *func , queryGlobalOperators(cppClass)) {
+ if (!lst.contains(func))
+ lst.append(func);
+ }
+
+ return lst;
+ //return cpp_class->functions();
+}
+
+AbstractMetaFunctionList Generator::queryGlobalOperators(const AbstractMetaClass *cppClass)
+{
+ AbstractMetaFunctionList result;
+
+ foreach (AbstractMetaFunction *func, cppClass->functions()) {
+ if (func->isInGlobalScope() && func->isOperatorOverload())
+ result.append(func);
+ }
+ return result;
+}
+
+AbstractMetaFunctionList Generator::sortContructor(AbstractMetaFunctionList list)
+{
+ AbstractMetaFunctionList result;
+
+ foreach (AbstractMetaFunction *func, list) {
+ bool inserted = false;
+ foreach (AbstractMetaArgument *arg, func->arguments()) {
+ if (arg->type()->isFlags() || arg->type()->isEnum()) {
+ result.push_back(func);
+ inserted = true;
+ break;
+ }
+ }
+ if (!inserted)
+ result.push_front(func);
+ }
+
+ return result;
+}
+
+FunctionModificationList Generator::functionModifications(const AbstractMetaFunction *metaFunction)
+{
+ FunctionModificationList mods;
+ const AbstractMetaClass *cls = metaFunction->implementingClass();
+ while (cls) {
+ mods += metaFunction->modifications(cls);
+
+ if (cls == cls->baseClass())
+ break;
+ cls = cls->baseClass();
+ }
+ return mods;
+}
+
+static QString formattedCodeHelper(QTextStream &s, Indentor &indentor, QStringList &lines)
+{
+ bool multilineComment = false;
+ bool lastEmpty = true;
+ QString lastLine;
+ while (!lines.isEmpty()) {
+ const QString line = lines.takeFirst().trimmed();
+ if (line.isEmpty()) {
+ if (!lastEmpty)
+ s << endl;
+ lastEmpty = true;
+ continue;
+ } else
+ lastEmpty = false;
+
+ if (line.startsWith("/*"))
+ multilineComment = true;
+
+ if (multilineComment) {
+ s << indentor;
+ if (line.startsWith("*"))
+ s << " ";
+ s << line << endl;
+ if (line.endsWith("*/"))
+ multilineComment = false;
+ } else if (line.startsWith("}"))
+ return line;
+ else if (line.endsWith("")) {
+ s << indentor << line << endl;
+ return 0;
+ } else if (line.endsWith("{")) {
+ s << indentor << line << endl;
+ QString tmp;
+ {
+ Indentation indent(indentor);
+ tmp = formattedCodeHelper(s, indentor, lines);
+ }
+ if (!tmp.isNull())
+ s << indentor << tmp << endl;
+
+ lastLine = tmp;
+ continue;
+ } else {
+ s << indentor;
+ if (!lastLine.isEmpty() &&
+ !lastLine.endsWith(";") &&
+ !line.startsWith("@") &&
+ !line.startsWith("//") &&
+ !lastLine.startsWith("//") &&
+ !lastLine.endsWith("}") &&
+ !line.startsWith("{"))
+ s << " ";
+ s << line << endl;
+ }
+ lastLine = line;
+ }
+ return 0;
+}
+
+QTextStream& formatCode(QTextStream &s, const QString& code, Indentor &indentor)
+{
+ QStringList lst(code.split("\n"));
+ while (!lst.isEmpty()) {
+ QString tmp = formattedCodeHelper(s, indentor, lst);
+ if (!tmp.isNull())
+ s << indentor << tmp << endl;
+
+ }
+ s.flush();
+ return s;
+}
+
+CodeSnipList Generator::getCodeSnips(const AbstractMetaFunction *func)
+{
+ CodeSnipList result;
+ const AbstractMetaClass *cppClass = func->implementingClass();
+ while (cppClass) {
+ foreach (FunctionModification mod, func->modifications(cppClass)) {
+ if (mod.isCodeInjection())
+ result << mod.snips;
+ }
+
+ if (cppClass == cppClass->baseClass())
+ break;
+ cppClass = cppClass->baseClass();
+ }
+
+ return result;
+}