umbrello API Documentation

csharpwriter.cpp

00001 /***************************************************************************
00002  *                                                                         *
00003  *   This program is free software; you can redistribute it and/or modify  *
00004  *   it under the terms of the GNU General Public License as published by  *
00005  *   the Free Software Foundation; either version 2 of the License, or     *
00006  *   (at your option) any later version.                                   *
00007  *                                                                         *
00008  *   copyright (C) 2007                                                    *
00009  *   Umbrello UML Modeller Authors <uml-devel@uml.sf.net>                  *
00010  ***************************************************************************/
00011 
00012 //
00013 // C++ Implementation: csharpwriter
00014 //
00015 #include "csharpwriter.h"
00016 
00017 #include <kdebug.h>
00018 #include <qregexp.h>
00019 #include <qtextstream.h>
00020 
00021 #include "../uml.h"
00022 #include "../umldoc.h"
00023 #include "../folder.h"
00024 #include "../classifier.h"
00025 #include "../association.h"
00026 #include "../attribute.h"
00027 #include "../operation.h"
00028 #include "../umlnamespace.h"
00029 
00030 static const char *reserved_words[] = {
00031     "abstract",
00032     "as",
00033     "base",
00034     "bool",
00035     "break",
00036     "byte",
00037     "case",
00038     "catch",
00039     "char",
00040     "checked",
00041     "class",
00042     "const",
00043     "continue",
00044     "decimal",
00045     "default",
00046     "delegate",
00047     "do",
00048     "double",
00049     "else",
00050     "enum",
00051     "event",
00052     "explicit",
00053     "extern",
00054     "false",
00055     "finally",
00056     "for",
00057     "foreach",
00058     "goto",
00059     "if",
00060     "implicit",
00061     "in",
00062     "int",
00063     "interface",
00064     "internal",
00065     "is",
00066     "lock",
00067     "long",
00068     "namespace",
00069     "new",
00070     "null",
00071     "object",
00072     "operator",
00073     "out",
00074     "override",
00075     "params",
00076     "private",
00077     "protected",
00078     "public",
00079     "readonly",
00080     "ref",
00081     "return",
00082     "sbyte",
00083     "sealed",
00084     "short",
00085     "sizeof",
00086     "stackalloc",
00087     "static",
00088     "string",
00089     "struct",
00090     "switch",
00091     "this",
00092     "throw",
00093     "true",
00094     "try",
00095     "typeof",
00096     "uint",
00097     "ulong",
00098     "unchecked",
00099     "unsafe",
00100     "ushort",
00101     "using",
00102     "virtual",
00103     "void",
00104     "volatile",
00105     "while",
00106     0
00107 };
00108 
00109 CSharpWriter::CSharpWriter()
00110  : SimpleCodeGenerator()
00111 {
00112 }
00113 
00114 
00115 CSharpWriter::~CSharpWriter()
00116 {
00117 }
00118 
00119 QStringList CSharpWriter::defaultDatatypes() {
00120     QStringList l;
00121     l.append("bool");
00122     l.append("byte");
00123     l.append("char");
00124     l.append("decimal");
00125     l.append("double");
00126     l.append("fixed");
00127     l.append("float");
00128     l.append("fixed");
00129     l.append("float");
00130     l.append("int");
00131     l.append("long");
00132     l.append("object");
00133     l.append("sbyte");
00134     l.append("short");
00135     l.append("string");
00136     l.append("uint");
00137     l.append("ulong");
00138     l.append("ushort");
00139     return l;
00140 }
00141 
00142 void CSharpWriter::writeClass(UMLClassifier *c) {
00143     if (!c) {
00144         kDebug()<<"Cannot write class of NULL concept!" << endl;
00145         return;
00146     }
00147 
00148     QString classname = cleanName(c->getName());
00149     //find an appropriate name for our file
00150     QString fileName = findFileName(c, ".cs");
00151     if (fileName.isEmpty()) {
00152         emit codeGenerated(c, false);
00153         return;
00154     }
00155 
00156     QFile filecs;
00157     if (!openFile(filecs, fileName)) {
00158         emit codeGenerated(c, false);
00159         return;
00160     }
00161     QTextStream cs(&filecs);
00162 
00164     //Start generating the code!!
00166 
00167 
00168     //try to find a heading file (license, coments, etc)
00169     QString str;
00170     str = getHeadingFile(".cs");
00171     if (!str.isEmpty()) {
00172         str.replace(QRegExp("%filename%"),fileName);
00173         str.replace(QRegExp("%filepath%"),filecs.name());
00174         cs<<str<<m_endl;
00175     }
00176 
00177     UMLDoc *umldoc = UMLApp::app()->getDocument();
00178     UMLFolder *logicalView = umldoc->getRootFolder(Uml::mt_Logical);
00179 
00180     // write generic includes
00181     cs << "using System;" << m_endl;
00182     cs << "using System.Text;" << m_endl;
00183     cs << "using System.Collections;" << m_endl;
00184     cs << "using System.Collections.Generic;" << m_endl << m_endl;
00185 
00186     //write includes and namespace
00187 
00188     UMLPackage *container = c->getUMLPackage();
00189     if (container == logicalView)
00190         container = NULL;
00191 
00192     UMLPackageList includes;
00193     findObjectsRelated(c, includes);
00194     m_seenIncludes.clear();
00195     //m_seenIncludes.append(logicalView);
00196     if (includes.count()) {
00197         UMLPackage *p;
00198         for (UMLPackageListIt it(includes); (p = it.current()) != NULL; ++it) {
00199             UMLClassifier *cl = dynamic_cast<UMLClassifier*>(p);
00200             if (cl)
00201                 p = cl->getUMLPackage();
00202             if (p != logicalView && m_seenIncludes.findRef(p) == -1 && p != container) {
00203                 cs << "using " << p->getFullyQualifiedName(".") << ";" << m_endl;
00204                 m_seenIncludes.append(p);
00205             }
00206         }
00207         cs << m_endl;
00208     }
00209 
00210     m_container_indent = "";
00211 
00212     if (container) {
00213         cs << "namespace " << container->getFullyQualifiedName(".") << m_endl;
00214         cs << "{" << m_endl << m_endl;
00215         m_container_indent = m_indentation;
00216         m_seenIncludes.append(container);
00217     }
00218 
00219     //Write class Documentation if there is somthing or if force option
00220     if (forceDoc() || !c->getDoc().isEmpty()) {
00221         cs << m_container_indent << "
00222         cs << formatDoc(c->getDoc(), m_container_indent + "
00223         cs << m_container_indent << "
00224     }
00225 
00226     UMLClassifierList superclasses = c->getSuperClasses();
00227     UMLAssociationList aggregations = c->getAggregations();
00228     UMLAssociationList compositions = c->getCompositions();
00229     UMLAssociationList realizations = c->getRealizations();
00230     bool isInterface = c->isInterface();
00231     m_unnamedRoles = 1;
00232 
00233     cs << m_container_indent << "public ";
00234 
00235     //check if it is an interface or regular class
00236     if (isInterface) {
00237         cs << "interface " << classname;
00238     } else {
00239         //check if class is abstract and / or has abstract methods
00240         if (c->getAbstract() || c->hasAbstractOps())
00241             cs << "abstract ";
00242 
00243         cs << "class " << classname << (superclasses.count() > 0 ? " : ":"");
00244 
00245         // write baseclass, ignore interfaces, write error on multiple inheritance
00246         if (superclasses.count() > 0) {
00247             UMLClassifier *obj;
00248             int supers = 0;
00249             for (obj = superclasses.first(); obj; obj = superclasses.next()) {
00250                 if (!obj->isInterface()) {
00251                     if (supers > 0) {
00252                         cs << " // AND ";
00253                     }
00254                     cs << cleanName(obj->getName());
00255                     supers++;
00256                 }
00257             }
00258             if (supers > 1) {
00259                 cs << m_endl << "//WARNING: C# does not support multiple inheritance but there is more than 1 superclass defined in your UML model!" << m_endl;
00260         }
00261         }
00262         //check for realizations
00263         UMLAssociationList realizations = c->getRealizations();
00264         UMLAssociation *a;
00265 
00266         if (!realizations.isEmpty()) {
00267             for (a = realizations.first(); a; a = realizations.next()) {
00268                 UMLClassifier *real = (UMLClassifier*)a->getObject(Uml::B);
00269                 if(real != c) {
00270                     // write list of realizations
00271                     cs << ", " << real->getName();
00272                 }
00273 
00274             }
00275         }
00276     }
00277     cs << m_endl << m_container_indent << '{' << m_endl;
00278 
00279     //associations
00280     if (forceSections() || !aggregations.isEmpty()) {
00281         cs << m_endl << m_container_indent << m_indentation << "#region Aggregations" << m_endl << m_endl;
00282         writeAssociatedAttributes(aggregations, c, cs);
00283         cs << m_endl << m_container_indent << m_indentation << "#endregion" << m_endl;
00284     }
00285 
00286     //compositions
00287     if (forceSections() || !compositions.isEmpty()) {
00288         cs << m_endl << m_container_indent << m_indentation << "#region Compositions" << m_endl << m_endl;
00289         writeAssociatedAttributes(compositions, c, cs);
00290         cs << m_endl << m_container_indent << m_indentation << "#endregion" << m_endl;
00291     }
00292 
00293     //attributes
00294     // FIXME: C# allows Properties in interface!
00295     if (!isInterface)
00296         writeAttributes(c, cs);
00297 
00298     //operations
00299     writeOperations(c, cs);
00300 
00301     //finish file
00302     cs << m_endl << m_container_indent << "}" << m_endl << m_endl; // close class
00303 
00304     if (container) {
00305         cs << "}  // end of namespace "
00306             << container->getFullyQualifiedName(".") << m_endl << m_endl;
00307     }
00308 
00309     //close files and notfiy we are done
00310     filecs.close();
00311     emit codeGenerated(c, true);
00312 }
00313 
00315 //  Helper Methods
00316 
00317 void CSharpWriter::writeOperations(UMLClassifier *c, QTextStream &cs) {
00318 
00319     //Lists to store operations  sorted by scope
00320     UMLOperationList oppub,opprot,oppriv;
00321 
00322     bool isInterface = c->isInterface();
00323     bool generateErrorStub = true;
00324 
00325     oppub.setAutoDelete(false);
00326     opprot.setAutoDelete(false);
00327     oppriv.setAutoDelete(false);
00328 
00329     //sort operations by scope first and see if there are abstract methods
00330     UMLOperationList opl(c->getOpList());
00331     for (UMLOperation *op = opl.first(); op ; op = opl.next()) {
00332         switch (op->getVisibility()) {
00333           case Uml::Visibility::Public:
00334             oppub.append(op);
00335             break;
00336           case Uml::Visibility::Protected:
00337             opprot.append(op);
00338             break;
00339           case Uml::Visibility::Private:
00340             oppriv.append(op);
00341             break;
00342           default:
00343             break;
00344         }
00345     }
00346 
00347     // write realizations (recursive)
00348     UMLAssociationList realizations = c->getRealizations();
00349 
00350     if (!isInterface && !realizations.isEmpty()) {
00351         writeRealizationsRecursive(c, &realizations, cs);
00352     }
00353 
00354     // write public operations
00355     if (forceSections() || !oppub.isEmpty()) {
00356         cs << m_endl << m_container_indent << m_indentation << "#region Public methods" << m_endl << m_endl;
00357         writeOperations(oppub,cs,isInterface,false,generateErrorStub);
00358         cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
00359     }
00360 
00361     // write protected operations
00362     if (forceSections() || !opprot.isEmpty()) {
00363         cs << m_endl << m_container_indent << m_indentation << "#region Protected methods" << m_endl << m_endl;
00364         writeOperations(opprot,cs,isInterface,false,generateErrorStub);
00365         cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
00366     }
00367 
00368     // write private operations
00369     if (forceSections() || !oppriv.isEmpty()) {
00370         cs << m_endl << m_container_indent << m_indentation << "#region Private methods" << m_endl << m_endl;
00371         writeOperations(oppriv,cs,isInterface,false,generateErrorStub);
00372         cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
00373     }
00374 
00375     // write superclasses abstract methods
00376     UMLClassifierList superclasses = c->getSuperClasses();
00377 
00378     if (!isInterface && !c->getAbstract() && !c->hasAbstractOps()
00379             && superclasses.count() > 0) {
00380         writeOverridesRecursive(&superclasses, cs);
00381     }
00382 
00383 }
00384 
00385 void CSharpWriter::writeOverridesRecursive(UMLClassifierList *superclasses, QTextStream &cs) {
00386     // oplist for implemented abstract operations
00387     UMLOperationList opabstract;
00388     opabstract.setAutoDelete(false);
00389     UMLClassifier *obj;
00390 
00391     for (obj = superclasses->first(); obj; obj = superclasses->next()) {
00392         if (!obj->isInterface() && obj->hasAbstractOps()) {
00393             // collect abstract ops
00394             UMLOperationList opl(obj->getOpList());
00395             for (UMLOperation *op = opl.first(); op ; op = opl.next()) {
00396                 if (op->getAbstract()) {
00397                     opabstract.append(op);
00398                 }
00399             }
00400 
00401             // write abstract implementations
00402             cs << m_endl << m_container_indent << m_indentation << "#region " << obj->getName() << " members" << m_endl << m_endl;
00403             writeOperations(opabstract,cs,false,true,true);
00404             cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
00405 
00406             opabstract.clear();
00407         }
00408         // Recurse to parent superclasses
00409         UMLClassifierList superRecursive = obj->getSuperClasses();
00410         UMLClassifierList *superRecursivePtr =& superRecursive;
00411         if (superRecursivePtr->count() > 0) {
00412             writeOverridesRecursive(superRecursivePtr, cs);
00413         }
00414     }
00415 }
00416 void CSharpWriter::writeRealizationsRecursive(UMLClassifier *currentClass, UMLAssociationList *realizations, QTextStream &cs) {
00417 
00418     UMLAssociation *a;
00419     for (a = realizations->first(); a; a = realizations->next()) {
00420 
00421         // we know its a classifier if its in the list
00422         UMLClassifier *real = (UMLClassifier*)a->getObject(Uml::B);
00423 
00424         //FIXME: Interfaces realize themselves without this condition!?
00425         if (real == currentClass)
00426             continue;
00427 
00428         // collect operations of one realization
00429         UMLOperationList opreal = real->getOpList();
00430 
00431         // write realizations
00432         cs << m_endl << m_container_indent << m_indentation << "#region " << real->getName() << " members" << m_endl << m_endl;
00433         writeOperations(opreal,cs,false,false,true);
00434         cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
00435 
00436         // Recurse to parent realizations
00437         UMLAssociationList parentReal = real->getRealizations();
00438         if (!parentReal.isEmpty()) {
00439             writeRealizationsRecursive(real, &parentReal, cs);
00440         }
00441     }
00442 }
00443 
00444 void CSharpWriter::writeOperations(UMLOperationList opList,
00445                                  QTextStream &cs, bool isInterface /* = false */,
00446                                  bool isOverride /* = false */,
00447                                  bool generateErrorStub /* = false */) {
00448 
00449     for (UMLOperation *op=opList.first(); op ; op=opList.next()) {
00450         UMLAttributeList atl = op->getParmList();
00451         UMLAttribute *at;
00452 
00453         //write method doc if we have doc || if at least one of the params has doc
00454         bool writeDoc = forceDoc() || !op->getDoc().isEmpty();
00455 
00456         for (at = atl.first(); at; at = atl.next()) {
00457             writeDoc |= !at->getDoc().isEmpty();
00458         }
00459 
00460         //write method documentation
00461         if (writeDoc && !isOverride)
00462         {
00463             cs << m_container_indent << m_indentation << "
00464             cs << formatDoc(op->getDoc(), m_container_indent + m_indentation + "
00465             cs << m_container_indent << m_indentation << "
00466 
00467             //write parameter documentation
00468             for (at = atl.first(); at; at = atl.next())
00469             {
00470                 if (forceDoc() || !at->getDoc().isEmpty()) {
00471                     cs << m_container_indent << m_indentation << "
00472                     //removing newlines from parameter doc
00473                     cs << formatDoc(at->getDoc(), "").replace("\n", " ").remove('\r').replace(QRegExp(" $"), "");
00474                     cs << "</param>" << m_endl;
00475                 }
00476             }
00477 
00478             // FIXME: "returns" should contain documentation, not type.
00479             cs << m_container_indent << m_indentation << "
00480             if (op->getTypeName() != "") {
00481                 cs << makeLocalTypeName(op);
00482             }
00483             cs << "</returns>" << m_endl;
00484 
00485         }
00486 
00487         // method visibility
00488         cs << m_container_indent << m_indentation;
00489         if (!isInterface) {
00490             if (!isOverride) {
00491                 if (op->getAbstract()) cs << "abstract ";
00492                 cs << op->getVisibility().toString() << " ";
00493                 if (op->getStatic()) cs << "static ";
00494             }
00495             else {
00496                 // method overriding an abstract parent
00497                 cs << op->getVisibility().toString() << " override ";
00498                 if (op->getStatic()) cs << "static ";
00499             }
00500         }
00501 
00502         // return type
00503         if (op->getTypeName() == "") {
00504             cs << "void ";
00505         }
00506         else {
00507             cs << makeLocalTypeName(op) << " ";
00508         }
00509 
00510         // method name
00511         cs << cleanName(op->getName()) << "(";
00512 
00513         // method parameters
00514         int i= atl.count();
00515         int j=0;
00516         for (at = atl.first(); at; at = atl.next(), j++) {
00517 
00518             cs << makeLocalTypeName(at) << " " << cleanName(at->getName());
00519 
00520             // no initial values in C#
00521             //<< (!(at->getInitialValue().isEmpty()) ?
00522             //    (QString(" = ")+at->getInitialValue()) :
00523             //    QString(""))
00524             cs << ((j < i-1)?", ":"");
00525         }
00526         cs << ")";
00527 
00528         //FIXME: how to control generation of error stub?
00529         if (!isInterface && (!op->getAbstract() || isOverride)) {
00530             cs << m_endl << m_container_indent << m_indentation << "{" << m_endl;
00531             if (generateErrorStub) {
00532                 cs << m_container_indent << m_indentation << m_indentation;
00533                 cs << "throw new Exception(\"The method or operation is not implemented.\");" << m_endl;
00534             }
00535             cs << m_container_indent << m_indentation << "}" << m_endl;
00536         }
00537         else {
00538             cs << ';' << m_endl;
00539         }
00540         cs << m_endl;
00541     }
00542 }
00543 
00544 void CSharpWriter::writeAttributes(UMLClassifier *c, QTextStream &cs) {
00545 
00546     UMLAttributeList  atpub, atprot, atpriv, atdefval;
00547     atpub.setAutoDelete(false);
00548     atprot.setAutoDelete(false);
00549     atpriv.setAutoDelete(false);
00550     atdefval.setAutoDelete(false);
00551 
00552     //sort attributes by scope and see if they have a default value
00553     UMLAttributeList atl = c->getAttributeList();
00554     UMLAttribute *at;
00555 
00556     for (at = atl.first(); at ; at = atl.next()) {
00557         if (!at->getInitialValue().isEmpty())
00558             atdefval.append(at);
00559         switch (at->getVisibility()) {
00560           case Uml::Visibility::Public:
00561             atpub.append(at);
00562             break;
00563           case Uml::Visibility::Protected:
00564             atprot.append(at);
00565             break;
00566           case Uml::Visibility::Private:
00567             atpriv.append(at);
00568             break;
00569           default:
00570             break;
00571         }
00572     }
00573 
00574     if (forceSections() || atl.count())
00575         cs << m_endl << m_container_indent << m_indentation << "#region Attributes" << m_endl << m_endl;
00576 
00577     // write public attributes
00578     if (forceSections() || atpub.count()) {
00579         writeAttributes(atpub,cs);
00580     }
00581 
00582     // write protected attributes
00583     if (forceSections() || atprot.count()) {
00584         writeAttributes(atprot,cs);
00585     }
00586 
00587     // write private attributes
00588     if (forceSections() || atpriv.count()) {
00589         writeAttributes(atpriv,cs);
00590     }
00591 
00592     if (forceSections() || atl.count())
00593         cs << m_endl << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
00594 
00595 }
00596 
00597 
00598 void CSharpWriter::writeAttributes(UMLAttributeList &atList, QTextStream &cs) {
00599 
00600     for (UMLAttribute *at = atList.first(); at ; at = atList.next()) {
00601 
00602         bool asProperty = true;
00603         if (at->getVisibility() == Uml::Visibility::Private) {
00604             asProperty = false;
00605         }
00606         writeAttribute(at->getDoc(), at->getVisibility(), at->getStatic(),
00607             makeLocalTypeName(at), at->getName(), at->getInitialValue(), asProperty, cs);
00608 
00609         cs << m_endl;
00610     } // end for
00611     return;
00612 }
00613 
00614 void CSharpWriter::writeAssociatedAttributes(UMLAssociationList &associated, UMLClassifier *c, QTextStream &cs) {
00615 
00616     UMLAssociation *a;
00617     for (a = associated.first(); a ; a = associated.next()) {
00618         if (c != a->getObject(Uml::A))  // we need to be at the A side
00619             continue;
00620 
00621         UMLObject *o = a->getObject(Uml::B);
00622         if (o == NULL) {
00623             kError() << "composition role B object is NULL" << endl;
00624             continue;
00625         }
00626         // Take name and documentaton from Role, take type name from the referenced object
00627         QString roleName = cleanName(a->getRoleName(Uml::B));
00628         QString typeName = cleanName(o->getName());
00629         if (roleName.isEmpty()) {
00630             roleName = QString("UnnamedRoleB_%1").arg(m_unnamedRoles++);
00631         }
00632         QString roleDoc = a->getRoleDoc(Uml::B);
00633 
00634         //FIXME:is this simple condition enough?
00635         if (a->getMulti(Uml::B).isEmpty() || a->getMulti(Uml::B) == "1")  {
00636             // normal attribute
00637             writeAttribute(roleDoc, a->getVisibility(Uml::B), false, typeName, roleName, "", ( a->getVisibility(Uml::B) != Uml::Visibility::Private), cs);
00638         } else {
00639             // array
00640             roleDoc += "\n(Array of " + typeName + ")";
00641             writeAttribute(roleDoc, a->getVisibility(Uml::B), false, "ArrayList", roleName, "", ( a->getVisibility(Uml::B) != Uml::Visibility::Private), cs);
00642         }
00643     }
00644 }
00645 
00646 void CSharpWriter::writeAttribute(QString doc, Uml::Visibility visibility, bool isStatic, QString typeName, QString name, QString initialValue, bool asProperty, QTextStream &cs) {
00647 
00648     if (forceDoc() || !doc.isEmpty()) {
00649 
00650         cs << m_container_indent << m_indentation << "
00651         cs << formatDoc(doc, m_container_indent + m_indentation + "
00652         cs << m_container_indent << m_indentation << "
00653 
00654     }
00655     cs << m_container_indent << m_indentation;
00656     cs << visibility.toString() << " ";
00657     if (isStatic) cs << "static ";
00658 
00659     //Variable type with/without namespace path
00660     cs << typeName << " ";
00661 
00662     cs << cleanName(name);
00663 
00664     // FIXME: may need a GUI switch to not generate as Property?
00665 
00666     // Generate as Property if not private
00667     if (asProperty)
00668     {
00669         cs << m_endl;
00670         cs << m_container_indent << m_indentation << "{" << m_endl;
00671         cs << m_container_indent << m_indentation << m_indentation << "get" << m_endl;
00672         cs << m_container_indent << m_indentation << m_indentation << "{" << m_endl;
00673         cs << m_container_indent << m_indentation << m_indentation << m_indentation << "return m_" << cleanName(name) << ";" << m_endl;
00674         cs << m_container_indent << m_indentation << m_indentation << "}" << m_endl;
00675 
00676         cs << m_container_indent << m_indentation << m_indentation << "set" << m_endl;
00677         cs << m_container_indent << m_indentation << m_indentation << "{" << m_endl;
00678         cs << m_container_indent << m_indentation << m_indentation << m_indentation << "m_" << cleanName(name) << " = value;" << m_endl;
00679         cs << m_container_indent << m_indentation << m_indentation << "}" << m_endl;
00680         cs << m_container_indent << m_indentation << "}" << m_endl;
00681         cs << m_container_indent << m_indentation << "private ";
00682         if (isStatic) cs << "static ";
00683         cs << typeName << " m_" << cleanName(name);
00684     }
00685 
00686     if (!initialValue.isEmpty())
00687         cs << " = " << initialValue;
00688 
00689     cs << ";" << m_endl << m_endl;
00690 }
00691 
00692 QString CSharpWriter::makeLocalTypeName(UMLClassifierListItem *cl) {
00693     UMLPackage *p = cl->getType()->getUMLPackage();
00694     if (m_seenIncludes.findRef(p) != -1) {
00695         return cl->getType()->getName();
00696     }
00697     else {
00698         return cl->getTypeName();
00699     }
00700 
00701 }
00702 
00706 Uml::Programming_Language CSharpWriter::getLanguage() {
00707     return Uml::pl_CSharp;
00708 }
00709 
00710 const QStringList CSharpWriter::reservedKeywords() const {
00711 
00712     static QStringList keywords;
00713 
00714     if (keywords.isEmpty()) {
00715         for (int i = 0; reserved_words[i]; i++)
00716             keywords.append(reserved_words[i]);
00717     }
00718 
00719     return keywords;
00720 }
00721 
00722 #include "csharpwriter.moc"
00723 
KDE Logo
This file is part of the documentation for umbrello Version 3.1.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Jun 26 08:07:56 2007 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003