diff options
author | Hugo Lima <hugo.lima@openbossa.org> | 2009-08-21 18:13:34 -0300 |
---|---|---|
committer | Hugo Lima <hugo.lima@openbossa.org> | 2009-08-25 16:23:16 -0300 |
commit | 55dd77e04a8cef0e14648d6d8fb18cdc18695931 (patch) | |
tree | d6533b9b8e741050a6c6ccd9c5abab561767739d /generator.cpp | |
parent | 9682566c558674609a77540978e36db3dd174303 (diff) |
- QtDocGenerator is now a GeneratorRunner plugin.
- A lot of methods moved from boostpythongenerator to the generator class.
Diffstat (limited to 'generator.cpp')
-rw-r--r-- | generator.cpp | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/generator.cpp b/generator.cpp index 343ebc63e..300406356 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; +} |