/*************************************************************************** pythonwriter.h - description ------------------- begin : Sat Dec 21 2002 copyright : Vincent Decorges email : vincent.decorges@eivd.ch (C) 2003-2006 Umbrello UML Modeller Authors ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "pythonwriter.h" #include #include #include #include #include #include #include "../umldoc.h" #include "../umlattributelist.h" #include "../association.h" #include "../attribute.h" #include "../classifier.h" #include "../attribute.h" #include "../operation.h" #include "../umlnamespace.h" PythonWriter::PythonWriter() : m_bNeedPass(true) { } PythonWriter::~PythonWriter() {} void PythonWriter::writeClass(UMLClassifier *c) { if(!c) { kDebug()<<"Cannot write class of NULL concept!" << endl; return; } TQString classname = cleanName(c->getName()); UMLClassifierList superclasses = c->getSuperClasses(); UMLAssociationList aggregations = c->getAggregations(); UMLAssociationList compositions = c->getCompositions(); m_bNeedPass = true; //find an appropriate name for our file TQString fileName = findFileName(c, ".py"); if (fileName.isEmpty()) { emit codeGenerated(c, false); return; } TQChar first = fileName.at(0); //Replace the first letter of the filename because //python class begin with an upper caracter (convention) first = first.upper(); fileName = fileName.replace(0, 1, first); TQFile fileh; if( !openFile(fileh, fileName) ) { emit codeGenerated(c, false); return; } TQTextStream h(&fileh); ////////////////////////////// //Start generating the code!! ///////////////////////////// //try to find a heading file (license, coments, etc) TQString str; str = getHeadingFile(".py"); if(!str.isEmpty()) { str.replace(TQRegExp("%filename%"), fileName); str.replace(TQRegExp("%filepath%"), fileh.name()); h<getName()); TQString pkg = cleanName(c->getPackage()); if (!pkg.isEmpty()) str.prepend(pkg + '.'); TQStringList includesList = TQStringList(str); //save imported classes int i = superclasses.count(); for (UMLClassifier *classifier = superclasses.first(); classifier && i; classifier = superclasses.next(), i--) { str = cleanName(classifier->getName()); pkg = cleanName(classifier->getPackage()); if (!pkg.isEmpty()) str.prepend(pkg + '.'); includesList.append(str); h << "from " + str + " import *" << m_endl; } //write includes and take namespaces into account UMLPackageList includes; findObjectsRelated(c,includes); UMLPackage* conc; for(conc = includes.first(); conc ;conc = includes.next()) { TQString headerName = findFileName(conc, ".py"); if ( !headerName.isEmpty() ) { headerName.remove(TQRegExp(".py$")); first = headerName.at(0); first = first.upper(); headerName = headerName.replace(0, 1, first); str = headerName.replace(TQChar('/'),TQChar('.')); if (includesList.findIndex(str) < 0) // not yet imported h << "from " << str << " import *" << m_endl; } } h< 0 ? " (" : "(object)"); i = superclasses.count(); for (UMLClassifier *obj = superclasses.first(); obj && i; obj = superclasses.next(), i--) { h<getName())<<(i>1?", ":""); } h<<(superclasses.count() > 0 ? ")":"")<<":"<getDoc().isEmpty()) { h << m_indentation << "\"\"\"" << m_endl; h << formatDoc(c->getDoc(), m_indentation + ' ') << m_endl; h << m_indentation << ":version:" << m_endl; h << m_indentation << ":author:" << m_endl; h << m_indentation << "\"\"\"" << m_endl << m_endl; m_bNeedPass = false; } // attributes writeAttributes(c->getAttributeList(), h); //operations writeOperations(c,h); if (m_bNeedPass) h << m_indentation << "pass" << m_endl; //finish files h<getDoc(), m_indentation + ' ') << m_endl; Uml::Visibility vis = at->getVisibility(); py << m_indentation << cleanName(at->getName()) << " (" << vis.toString() << ")" << m_endl << m_endl ; } // end for py << m_indentation << "\"\"\"" << m_endl << m_endl; } void PythonWriter::writeOperations(UMLClassifier *c, TQTextStream &h) { //Lists to store operations sorted by scope UMLOperationList oppub,opprot,oppriv; oppub.setAutoDelete(false); opprot.setAutoDelete(false); oppriv.setAutoDelete(false); //sort operations by scope first and see if there are abstract methods UMLOperationList opl(c->getOpList()); for(UMLOperation *op = opl.first(); op ; op = opl.next()) { switch(op->getVisibility()) { case Uml::Visibility::Public: oppub.append(op); break; case Uml::Visibility::Protected: opprot.append(op); break; case Uml::Visibility::Private: oppriv.append(op); break; default: break; } } TQString classname(cleanName(c->getName())); //write operations to file if(forceSections() || !oppub.isEmpty()) { writeOperations(classname,oppub,h,PUBLIC); } if(forceSections() || !opprot.isEmpty()) { writeOperations(classname,opprot,h,PROTECTED); } if(forceSections() || !oppriv.isEmpty()) { writeOperations(classname,oppriv,h,PRIVATE); } } void PythonWriter::writeOperations(const TQString& /*classname*/, UMLOperationList &opList, TQTextStream &h, Access access) { UMLOperation *op; UMLAttribute *at; TQString sAccess; switch (access) { case PUBLIC: sAccess = TQString(""); break; case PRIVATE: sAccess = TQString("__"); break; case PROTECTED: sAccess = TQString("_"); break; } for(op=opList.first(); op ; op=opList.next()) { UMLAttributeList atl = op->getParmList(); //write method doc if we have doc || if at least one of the params has doc bool writeDoc = forceDoc() || !op->getDoc().isEmpty(); for (at = atl.first(); at; at = atl.next()) writeDoc |= !at->getDoc().isEmpty(); h<< m_indentation << "def "<< sAccess + cleanName(op->getName()) << "(self"; int j=0; for (at = atl.first(); at; at = atl.next(), j++) { h << ", " << cleanName(at->getName()) << (!(at->getInitialValue().isEmpty()) ? (TQString(" = ")+at->getInitialValue()) : TQString("")); } h<<"):"<getDoc(), m_indentation + m_indentation + ' ') << m_endl; for (at = atl.first(); at; at = atl.next()) //write parameter documentation { if(forceDoc() || !at->getDoc().isEmpty()) { h<getTypeName()<< " " << cleanName(at->getName()); h<<" : "<getDoc()<getTypeName()<<" :"<