From 124750d5e19a642f69f28a3299380bb95ba3d089 Mon Sep 17 00:00:00 2001 From: Konrad Rosenbaum Date: Sat, 18 Feb 2012 15:21:46 +0100 Subject: [PATCH] generate most docu tags in Qt output --- woc/doxyout.h | 40 ++++++++++++++++++++++++++++++++++++++++ woc/htmlout.cpp | 1 + woc/proc/procclass.cpp | 18 ++++++++++++++++++ woc/proc/procclass.h | 5 +++++ woc/qt/qtclass.cpp | 35 ++++++++++++++++++++++++++++++----- woc/qt/qtctrans.cpp | 47 +++++++++++++++++++++++++++++++++++++---------- woc/qt/qtout.cpp | 47 ++++++++++++++++++++++++++++++++++------------- woc/qt/qtout.h | 11 ++++++++++- 8 files changed, 175 insertions(+), 29 deletions(-) create mode 100644 woc/doxyout.h diff --git a/woc/doxyout.h b/woc/doxyout.h new file mode 100644 index 0000000..4b2064f --- /dev/null +++ b/woc/doxyout.h @@ -0,0 +1,40 @@ +// Copyright (C) 2012 by Konrad Rosenbaum +// protected under the GNU GPL version 3 or at your option any newer. +// See COPYING.GPL file that comes with this distribution. +// + +#ifndef WOC_DOXYOUT_H +#define WOC_DOXYOUT_H +#include + +inline QString doxyFormat(const QString&in,int level=0) +{ + //split to lines + QStringList inl=in.trimmed().split('\n'); + QString pre,ret; + //create indent and comment prefix + for(int i=0;i\n"; + hcd+="

"+cls.enumDoc(k[i])+"

\n"; hcd+=""; hcd+="\n"; QListev=cls.enumValues(k[i]); diff --git a/woc/proc/procclass.cpp b/woc/proc/procclass.cpp index f820f02..56d7d25 100644 --- a/woc/proc/procclass.cpp +++ b/woc/proc/procclass.cpp @@ -104,6 +104,7 @@ WocClass::WocClass(const QDomElement&cls) } QListev; //check whether there is a reference + QString coldoc; if(el.hasAttribute("refColumn")){ QStringList ref=el.attribute("refColumn").split(":"); if(ref.size()!=2){ @@ -123,6 +124,9 @@ WocClass::WocClass(const QDomElement&cls) return; } ev=tab.columnEnums(ref[1]); + coldoc+="Generated from table "+tab.name()+", column "+ref[1]+".\n\n"; + coldoc=tab.columnDoc(ref[1]); + coldoc=coldoc.trimmed(); } //scan values QList nl2=elementsByTagName(el,"Value"); @@ -141,6 +145,20 @@ WocClass::WocClass(const QDomElement&cls) //TODO: check that value name does not exist yet } m_enumvals.insert(nm,ev); + //scan docu + QString doc; + foreach(QDomElement el2,elementsByTagName(el,"Doc")){ + QString d=el2.text().trimmed(); + if(d.size()>0){ + if(doc.size()>0)doc+="\n\n"; + doc+=d; + } + } + if(coldoc.size()>0){ + if(doc.size()>0)doc+="\n\n"; + doc+=coldoc; + } + m_enumdoc.insert(nm,doc); } //scan mappings nl=elementsByTagName(cls,"Mapping"); diff --git a/woc/proc/procclass.h b/woc/proc/procclass.h index 456ffa1..ba23640 100644 --- a/woc/proc/procclass.h +++ b/woc/proc/procclass.h @@ -100,6 +100,9 @@ class WocClass /**returns documentation for a property*/ QString propDoc(QString p)const {if(m_propdoc.contains(p))return m_propdoc[p];else return "";} + /**returns base documentation for enums*/ + QString enumDoc(QString e)const + {if(m_enumdoc.contains(e))return m_enumdoc[e];else return QString();} private: //valid: parsing the WOLF succeeded @@ -125,6 +128,8 @@ class WocClass QMap >m_maps; //enum types: "type-name" => List of ("constant-name",int-constant-value) QMap >m_enumvals; + //enum types: "type-name" => "documentation" + QMapm_enumdoc; //serializers: "name" => List of properties (syntax Objects: "propertyname/Serializer" // QMap m_serial; diff --git a/woc/qt/qtclass.cpp b/woc/qt/qtclass.cpp index df29844..405e0e0 100644 --- a/woc/qt/qtclass.cpp +++ b/woc/qt/qtclass.cpp @@ -10,6 +10,7 @@ #include #include "qtconst.h" +#include "doxyout.h" WocQtClass::WocQtClass(WocQtOut* p) { @@ -32,6 +33,8 @@ void WocQtClass::newClass(const WocClass&cls) QString cna=cn; if(cls.isAbstract(m_lang))cna+="Abstract"; addFile(cna); + m_parent->addIfaceHeaderPrefix("class "+cn+";\n"); + if(cn!=cna)m_parent->addIfaceHeaderPrefix("class "+cna+";\n"); MFile hdr(m_basedir+"/"+m_subdir+"/src"+cna+".h"); MFile src(m_basedir+"/"+m_subdir+"/src"+cna+".cpp"); if(!hdr.open(QIODevice::WriteOnly|QIODevice::Truncate) || @@ -55,6 +58,7 @@ void WocQtClass::newClass(const WocClass&cls) //class declaration QString cnb=cls.baseClass(m_lang,m_prefix+"O"); + hcd+=doxyFormat(cls.docStrings()); hcd+="class "+cna+":public "+cnb+"\n{\n Q_OBJECT\n"; hdr.write(hcd.toAscii()); @@ -107,8 +111,10 @@ void WocQtClass::classScripting(const WocClass& cls, MFile& hdr, MFile& src, QSt } scd+="#include \n"; scd+="#include \n"; + scd+=doxyFormat("Convert "+cn+" to a value usable with the Qt script engine."); scd+="QScriptValue "+cn+"::toScriptValue(QScriptEngine*engine,const "+cn+"&obj)\n{\n"; scd+="\treturn engine->newQObject(new "+cn+"(obj),QScriptEngine::ScriptOwnership);\n}\n"; + scd+=doxyFormat("Convert from a Qt script engine value back to a "+cn+"."); scd+="void "+cn+"::fromScriptValue(const QScriptValue&val,"+cn+"&obj)\n{\n"; scd+="\t"+cn+"*xobj=qobject_cast<"+cn+"*>(val.toQObject());\n"; scd+="\tif(xobj!=0 && &obj!=xobj)obj = *xobj;\n}\n"; @@ -137,7 +143,8 @@ void WocQtClass::classEnums(const WocClass&cls,MFile&hdr,MFile&src,QString cn) scd+="static int enum_"+k[i]+"_metatypeid=qRegisterMetaType<"+cn+"::"+k[i]+">();\n"; scd+="static int enum_"+k[i]+"_metatypeid2=qRegisterMetaType >();\n"; //type - hcd+="\tenum "+k[i]+"{"; + hcd+=doxyFormat(cls.enumDoc(k[i]),1); + hcd+="\tenum "+k[i]+"{\n"; QListev=cls.enumValues(k[i]); if(ev.size()<1){ qDebug("Error: enums must have at least one member - class %s enum %s",cls.name().toAscii().data(),k[i].toAscii().data()); @@ -145,12 +152,15 @@ void WocQtClass::classEnums(const WocClass&cls,MFile&hdr,MFile&src,QString cn) return; } for(int j=0;j #include "qtconst.h" +#include "doxyout.h" WocQtClientTransaction::WocQtClientTransaction(WocQtOut*p) :WocQtTransaction(p) @@ -37,6 +38,7 @@ struct QtCTrans{ QString clist;//input param list, but call values only (val1,val2,...) QString xinlist;//input params plus interface name QString xclist;//input params plus interface name + QString indoc,ifcdoc;//docu for input params //transaction itself const WocTransaction&trn; QtCTrans(const WocTransaction&t,QString cn_,QString cnp_):trn(t){ @@ -72,7 +74,8 @@ void WocQtClientTransaction::newTransaction(const WocTransaction&trn) genInclude(ct); //start of class ct.hcd+="\nclass "+cnp+";\n"; - ct.hcd+="\nclass "+cn+":public "+m_transbase+"\n{\n Q_OBJECT\n"; + ct.hcd+="\n"+doxyFormat(trn.docStrings()); + ct.hcd+="class "+cn+":public "+m_transbase+"\n{\n Q_OBJECT\n"; ct.pcd+="\nclass "+cnp+":public WTransaction_PrivateBase\n{\n"; //create properties @@ -117,6 +120,9 @@ void WocQtClientTransaction::initList(QtCTrans& ct) if(i){ct.inlist+=",";ct.clist+=",";} ct.inlist+="const "+qttype(ct.trn,ct.in[i],WocQtOut::In)+"&a"+ct.in[i]; ct.clist+="a"+ct.in[i]; + ct.indoc+="\t/// \\param a"+ct.in[i]+" "; + ct.indoc+=ct.trn.inputDoc(ct.in[i]).replace('\n',' ').replace('\r',' '); + ct.indoc+="\n"; } ct.xinlist=ct.inlist; ct.xclist=ct.clist; @@ -124,6 +130,7 @@ void WocQtClientTransaction::initList(QtCTrans& ct) ct.xinlist+="QString iface"; if(ct.xclist!="")ct.xclist+=","; ct.xclist+="iface"; + ct.ifcdoc="\t/// \\param iface ID of the interface that the transaction will be sent on\n"; } @@ -161,6 +168,8 @@ void WocQtClientTransaction::genTors(QtCTrans&ct) { //define parametric constructor ct.hcd+=" protected:\n"; + ct.hcd+="\t/// generates an instance from its properties\n"; + ct.hcd+=ct.indoc+ct.ifcdoc; ct.hcd+="\texplicit "+ct.cn+"("+ct.xinlist+");\n"; //parametric constructor implementation ct.scd+=ct.cn+"::"+ct.cn+"("+ct.xinlist+")\n\t:"+m_transbase+"(iface)\n{\n"; @@ -171,15 +180,18 @@ void WocQtClientTransaction::genTors(QtCTrans&ct) ct.scd+="}\n\n"; //decl default constructor ct.hcd+=" public:\n"; + ct.hcd+="\t/// default constructor: generates an invalid transaction\n"; ct.hcd+="\t"+ct.cn+"();\n"; ct.scd+=ct.cn+"::"+ct.cn+"()\n{\n\tnew "+ct.cnp+"(this);\n}\n\n"; //decl copy constructor + ct.hcd+="\t/// copy constructor: the two copies share their state\n"; ct.hcd+="\t"+ct.cn+"(const "+ct.cn+"&);\n"; //copy constructor implementation ct.scd+=ct.cn+"::"+ct.cn+"(const "+ct.cn+"&t)\n\t:"+m_transbase+"(t)\n{\n"; ct.scd+="\tt.p->attach(this);\n"; ct.scd+="}\n\n"; //decl copy operator + ct.hcd+="\t/// copy assignment: the copy shares the state of the original object\n"; ct.hcd+="\t"+ct.cn+"& operator=(const "+ct.cn+"&);\n"; //copy operator implemented ct.scd+=ct.cn+"& "+ct.cn+"::operator=(const "+ct.cn+"&t)\n{\n"; @@ -189,6 +201,7 @@ void WocQtClientTransaction::genTors(QtCTrans&ct) ct.scd+="\treturn *this;\n}\n\n"; //destructor + ct.hcd+="\t/// deletes this instance\n"; ct.hcd+="\tvirtual ~"+ct.cn+"();\n"; ct.scd+=ct.cn+"::~"+ct.cn+"()\n{\n\tp->detach(this);\n}\n\n"; } @@ -196,9 +209,11 @@ void WocQtClientTransaction::genTors(QtCTrans&ct) void WocQtClientTransaction::genQuery(QtCTrans& ct) { //global interface code - QString sif=" Q_SLOT "+ct.cn+" query"+ct.trn.name()+"("+ct.inlist+")\n\t"; - sif+="{return "+ct.cn+"::query("+ct.clist+(ct.clist!=""?",":"")+"name());}\n"; - m_iface.write(sif.toAscii());sif.clear(); + m_parent->addIfaceHeaderPrefix("class "+ct.cn+";\n"); +// m_parent->addIfaceImpl("#include \"src"+ct.cn+".h\"\n"); + m_parent->addIfaceHeaderClass(" /// convenience call to query "+ct.cn+" synchronously\n"); + m_parent->addIfaceHeaderClass(" "+ct.cn+" query"+ct.trn.name()+"("+ct.inlist+");\n"); + m_parent->addIfaceImpl(ct.cn+" "+ m_parent->ifaceClassName()+"::query"+ct.trn.name()+ "("+ct.inlist+ ")\n{return "+ct.cn+"::query("+ ct.clist+(ct.clist!=""?",":"")+"name());}\n\n"); //query method decl ct.hcd+=" private:\n"; ct.hcd+="\tvoid netquery();\n\tvoid asyncnetquery();\n"; @@ -231,11 +246,15 @@ void WocQtClientTransaction::genQuery(QtCTrans& ct) ct.scd+="\temit finished();\n}\n"; //create queries ct.hcd+=" public:\n"; + ct.hcd+="\t/// emits the query over the network and returns the finished transaction object\n"; + ct.hcd+=ct.indoc+ct.ifcdoc; ct.hcd+="\tstatic "+ct.cn+" query("+ct.xinlist+ct.defparm+");\n"; ct.scd+=ct.cn+" "+ct.cn+"::query("+ct.xinlist+")\n{\n"; ct.scd+="\t"+ct.cn; ct.scd+=" r("+ct.xclist+");\n"; ct.scd+="\tr.netquery();\n\treturn r;\n}\n"; + ct.hcd+="\t/// emits the query over the network and returns the transaction object, use isFinished() to check for the transaction's state\n"; + ct.hcd+=ct.indoc+ct.ifcdoc; ct.hcd+="\tstatic "+ct.cn+" asyncQuery("+ct.xinlist+ct.defparm+");\n"; ct.scd+=ct.cn+" "+ct.cn+"::asyncQuery("+ct.xinlist+")\n{\n"; ct.scd+="\t"+ct.cn; @@ -247,6 +266,7 @@ void WocQtClientTransaction::genGetters(QtCTrans& ct) { for(int i=0;iout_"+ct.out[i]+";}\n"; } @@ -260,7 +280,9 @@ void WocQtClientTransaction::genScripting(QtCTrans& ct) ct.hdi+="class QScriptEngine;\n"; ct.sri+="#include \n"; ct.sri+="#include \n"; + ct.hcd+="\t/// Wraps the transaction so it can be used from scripts.\n"; ct.hcd+="\tstatic QScriptValue toScriptValue(QScriptEngine*,const "+ct.cn+"&);\n"; + ct.hcd+="\t/// Unwraps the transaction in the script value, so it can be used in C++ again.\n"; ct.hcd+="\tstatic void fromScriptValue(const QScriptValue&,"+ct.cn+"&);\n"; ct.scd+="QScriptValue "+ct.cn+"::toScriptValue(QScriptEngine*engine,const "+ct.cn+"&obj)\n{\n"; ct.scd+="\treturn engine->newQObject(new "+ct.cn+"(obj),QScriptEngine::ScriptOwnership);\n}\n"; @@ -415,14 +437,19 @@ void WocQtClientTransaction::trnList() QString code; //header code+=" Q_ENUMS(Right)\n"; - code+=" enum Right {\n NoRight"; + code+=" /// This enum represents transactions and the right to use them.\n" + code+=" enum Right {\n /// dummy as a fall back for no transaction\n NoRight"; QStringList r=WocProcessor::instance()->transactionNames(); QStringList p=WocProcessor::instance()->privilegeNames(); QStringList pp=p; - for(int i=0;iifaceClassName()+"::RightList allKnownRights();\n"; - m_iface.write(code.toAscii());code.clear(); + m_parent->addIfaceHeaderClass(code);code.clear(); code+="static int righttypeid="; code+="qRegisterMetaType<"+m_parent->ifaceClassName()+"::RightList>()+"; @@ -470,5 +497,5 @@ void WocQtClientTransaction::trnList() for(int i=0;iaddIfaceImpl(code); } diff --git a/woc/qt/qtout.cpp b/woc/qt/qtout.cpp index b368f77..f3189bb 100644 --- a/woc/qt/qtout.cpp +++ b/woc/qt/qtout.cpp @@ -14,6 +14,7 @@ #define QT_OUT_NO_WRAP #include "qtconst.h" +#include "doxyout.h" WocQtOut::WocQtOut(QDomElement&el) { @@ -57,27 +58,30 @@ WocQtOut::WocQtOut(QDomElement&el) return; } m_iface.write(QByteArray(HDRSTART).replace("%",m_prefix.toAscii()+"INTERFACE_H")); - m_iface.write(QByteArray("#include \""+m_prefix.toAscii()+"IncludeAll\"\n#include \"WInterface\"\n")); + m_iface.write(QByteArray("#include \"WInterface\"\n")); m_iface.write(QByteArray("#include \n")); if(m_genscript) m_iface.write(QByteArray("class QScriptEngine;\n")); - m_iface.write(QString("class "+ifaceClassName()+":public WInterface\n{\n Q_OBJECT\n").toAscii()); - m_iface.write(QString(" public:\n "+ifaceClassName()+"(QString name=\""+pn+"\"):WInterface(name){}\n").toAscii()); - m_iface.write(QString(" static "+ifaceClassName()+"*instance(QString name=\""+pn+"\")\n\t{return qobject_cast<"+ifaceClassName()+"*>(WInterface::instance(name));}\n\n").toAscii()); -// m_iface.write(QString(" Q_INVOKABLE static QString commVersion(){return \""+woc->verComm()+"\";}\n").toAscii()); -// m_iface.write(QString(" Q_INVOKABLE static QString needCommVersion(){return \""+woc->verNeedComm()+"\";}\n").toAscii()); -// m_iface.write(QString(" Q_INVOKABLE static QString version(){return \""+woc->verHR()+"\";}\n").toAscii()); + addIfaceHeaderClass(doxyFormat(pn+" interface class.")); + addIfaceHeaderClass(QString("class "+ifaceClassName()+":public WInterface\n{\n Q_OBJECT\n")); + addIfaceHeaderClass(QString(" public:\n "+ifaceClassName()+"(QString name=\""+pn+"\"):WInterface(name){}\n")); + addIfaceHeaderClass(" /// convenience override: returns a pointer to an instance with the given name if it is of the correct type, otherwise nullptr\n"); + addIfaceHeaderClass(" static "+ifaceClassName()+"*instance(QString name=\""+pn+"\")\n\t{return qobject_cast<"+ifaceClassName()+"*>(WInterface::instance(name));}\n\n"); //version info, static - m_iface.write(QByteArray(" Q_INVOKABLE static QString staticVersionInfo(WOb::VersionInfo);\n")); + addIfaceHeaderClass(" /// returns version information of this interface\n"); + addIfaceHeaderClass(" Q_INVOKABLE static QString staticVersionInfo(WOb::VersionInfo);\n"); + m_ifacecpp.write(QByteArray("#include \""+m_prefix.toAscii()+"IncludeAll\"\n")); m_ifacecpp.write(QByteArray("#include \"staticVersion.h\"\n")); m_ifacecpp.write(QString("QString "+ifaceClassName()+"::staticVersionInfo(WOb::VersionInfo vi){return WOCgenerated_versionInfo(vi);}\n").toAscii()); - m_iface.write(QByteArray(" Q_INVOKABLE static QString staticWocVersionInfo(WOb::VersionInfo);\n")); + addIfaceHeaderClass(" /// returns version information about the WOC that created the interface class\n"); + addIfaceHeaderClass(" Q_INVOKABLE static QString staticWocVersionInfo(WOb::VersionInfo);\n"); m_ifacecpp.write(QString("QString "+ifaceClassName()+"::staticWocVersionInfo(WOb::VersionInfo vi){return WOCcopied_versionInfo(vi);}\n").toAscii()); //version info, virtual - m_iface.write(QByteArray(" Q_INVOKABLE QString versionInfo(WOb::VersionInfo)const;\n")); - m_ifacecpp.write(QByteArray("#include \"staticVersion.h\"\n")); + addIfaceHeaderClass(" /// returns version information of this interface\n"); + addIfaceHeaderClass(" Q_INVOKABLE QString versionInfo(WOb::VersionInfo)const;\n"); m_ifacecpp.write(QString("QString "+ifaceClassName()+"::versionInfo(WOb::VersionInfo vi)const{return WOCgenerated_versionInfo(vi);}\n").toAscii()); - m_iface.write(QByteArray(" Q_INVOKABLE QString wocVersionInfo(WOb::VersionInfo)const;\n")); + addIfaceHeaderClass(" /// returns version information about the WOC that created the interface class\n"); + addIfaceHeaderClass(" Q_INVOKABLE QString wocVersionInfo(WOb::VersionInfo)const;\n"); m_ifacecpp.write(QString("QString "+ifaceClassName()+"::wocVersionInfo(WOb::VersionInfo vi)const{return WOCcopied_versionInfo(vi);}\n").toAscii()); //init scripting @@ -103,7 +107,7 @@ void WocQtOut::finalize() if(qtrans)qtrans->finalize(); //finish scripting stuff if(m_genscript){ - m_iface.write(QByteArray(" void initScriptEngine(QScriptEngine*);\n")); + addIfaceHeaderClass(" void initScriptEngine(QScriptEngine*);\n"); m_scriptcode+="}\n\n"; m_ifacecpp.write(m_scriptcode.toAscii()); } @@ -114,6 +118,8 @@ void WocQtOut::finalize() //finish sources m_ifacecpp.write(SRCEND); m_ifacecpp.close(); + m_iface.write(m_iface_prefix.toAscii()); + m_iface.write(m_iface_class.toAscii()); m_iface.write(QByteArray("};\n")); m_iface.write(m_postiface.toAscii()); m_iface.write(HDREND); @@ -333,3 +339,18 @@ void WocQtOut::initVersionH() //close file vhf.write(QByteArray(HDREND)); } + +void WocQtOut::addToPriFile ( const QByteArray& a ) +{ + m_pri.write(a); +} + +void WocQtOut::addToIncludeAllFile ( const QByteArray& a ) +{ + m_hdr.write(a); +} + +void WocQtOut::addIfaceImpl ( const QString& s ) +{ + m_ifacecpp.write(s.toAscii()); +} diff --git a/woc/qt/qtout.h b/woc/qt/qtout.h index 7c0b3da..7f72c0e 100644 --- a/woc/qt/qtout.h +++ b/woc/qt/qtout.h @@ -35,6 +35,13 @@ class WocQtOut:public WocOutput public: WocQtOut(QDomElement&); ~WocQtOut(); + + void addIfaceHeaderPrefix(const QString&s){m_iface_prefix+=s;} + void addIfaceHeaderClass(const QString&s){m_iface_class+=s;} + void addIfaceImpl(const QString&); + + void addToPriFile(const QByteArray&a); + void addToIncludeAllFile(const QByteArray&a); protected: virtual void finalize(); virtual void newClass(const WocClass&); @@ -48,7 +55,6 @@ class WocQtOut:public WocOutput friend class WocQtTable; QString m_basedir,m_subdir,m_prefix,m_transbase,m_lang,m_postiface,m_scriptcode; - MFile m_pri,m_iface,m_ifacecpp,m_hdr; bool m_clean,m_genscript; ///types of files generated @@ -89,6 +95,9 @@ class WocQtOut:public WocOutput WocQtClass*qclass; WocQtTable*qtable; WocQtTransaction*qtrans; + private: + MFile m_pri,m_iface,m_ifacecpp,m_hdr; + QString m_iface_prefix,m_iface_class; }; class WocQtClientOut:public WocQtOut -- 1.7.2.5
SymbolValueDocu