You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
726 lines
23 KiB
726 lines
23 KiB
/***************************************************************************
|
|
* *
|
|
* 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. *
|
|
* *
|
|
* copyright (C) 2007 *
|
|
* Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
|
|
***************************************************************************/
|
|
|
|
//
|
|
// C++ Implementation: csharpwriter
|
|
//
|
|
#include "csharpwriter.h"
|
|
|
|
#include <kdebug.h>
|
|
#include <tqregexp.h>
|
|
#include <tqtextstream.h>
|
|
|
|
#include "../uml.h"
|
|
#include "../umldoc.h"
|
|
#include "../folder.h"
|
|
#include "../classifier.h"
|
|
#include "../association.h"
|
|
#include "../attribute.h"
|
|
#include "../operation.h"
|
|
#include "../umlnamespace.h"
|
|
|
|
static const char *reserved_words[] = {
|
|
"abstract",
|
|
"as",
|
|
"base",
|
|
"bool",
|
|
"break",
|
|
"byte",
|
|
"case",
|
|
"catch",
|
|
"char",
|
|
"checked",
|
|
"class",
|
|
"const",
|
|
"continue",
|
|
"decimal",
|
|
"default",
|
|
"delegate",
|
|
"do",
|
|
"double",
|
|
"else",
|
|
"enum",
|
|
"event",
|
|
"explicit",
|
|
"extern",
|
|
"false",
|
|
"finally",
|
|
"for",
|
|
"foreach",
|
|
"goto",
|
|
"if",
|
|
"implicit",
|
|
"in",
|
|
"int",
|
|
"interface",
|
|
"internal",
|
|
"is",
|
|
"lock",
|
|
"long",
|
|
"namespace",
|
|
"new",
|
|
"null",
|
|
"object",
|
|
"operator",
|
|
"out",
|
|
"override",
|
|
"params",
|
|
"private",
|
|
"protected",
|
|
"public",
|
|
"readonly",
|
|
"ref",
|
|
"return",
|
|
"sbyte",
|
|
"sealed",
|
|
"short",
|
|
"sizeof",
|
|
"stackalloc",
|
|
"static",
|
|
"string",
|
|
"struct",
|
|
"switch",
|
|
"this",
|
|
"throw",
|
|
"true",
|
|
"try",
|
|
"typeof",
|
|
"uint",
|
|
"ulong",
|
|
"unchecked",
|
|
"unsafe",
|
|
"ushort",
|
|
"using",
|
|
"virtual",
|
|
"void",
|
|
"volatile",
|
|
"while",
|
|
0
|
|
};
|
|
|
|
CSharpWriter::CSharpWriter()
|
|
: SimpleCodeGenerator()
|
|
{
|
|
}
|
|
|
|
|
|
CSharpWriter::~CSharpWriter()
|
|
{
|
|
}
|
|
|
|
TQStringList CSharpWriter::defaultDatatypes() {
|
|
TQStringList l;
|
|
l.append("bool");
|
|
l.append("byte");
|
|
l.append("char");
|
|
l.append("decimal");
|
|
l.append("double");
|
|
l.append("fixed");
|
|
l.append("float");
|
|
l.append("fixed");
|
|
l.append("float");
|
|
l.append("int");
|
|
l.append("long");
|
|
l.append("object");
|
|
l.append("sbyte");
|
|
l.append("short");
|
|
l.append("string");
|
|
l.append("uint");
|
|
l.append("ulong");
|
|
l.append("ushort");
|
|
return l;
|
|
}
|
|
|
|
void CSharpWriter::writeClass(UMLClassifier *c) {
|
|
if (!c) {
|
|
kDebug()<<"Cannot write class of NULL concept!" << endl;
|
|
return;
|
|
}
|
|
|
|
TQString classname = cleanName(c->getName());
|
|
//find an appropriate name for our file
|
|
TQString fileName = findFileName(c, ".cs");
|
|
if (fileName.isEmpty()) {
|
|
emit codeGenerated(c, false);
|
|
return;
|
|
}
|
|
|
|
TQFile filecs;
|
|
if (!openFile(filecs, fileName)) {
|
|
emit codeGenerated(c, false);
|
|
return;
|
|
}
|
|
TQTextStream cs(&filecs);
|
|
|
|
//////////////////////////////
|
|
//Start generating the code!!
|
|
/////////////////////////////
|
|
|
|
|
|
//try to find a heading file (license, coments, etc)
|
|
TQString str;
|
|
str = getHeadingFile(".cs");
|
|
if (!str.isEmpty()) {
|
|
str.replace(TQRegExp("%filename%"),fileName);
|
|
str.replace(TQRegExp("%filepath%"),filecs.name());
|
|
cs<<str<<m_endl;
|
|
}
|
|
|
|
UMLDoc *umldoc = UMLApp::app()->getDocument();
|
|
UMLFolder *logicalView = umldoc->getRootFolder(Uml::mt_Logical);
|
|
|
|
// write generic includes
|
|
cs << "using System;" << m_endl;
|
|
cs << "using System.Text;" << m_endl;
|
|
cs << "using System.Collections;" << m_endl;
|
|
cs << "using System.Collections.Generic;" << m_endl << m_endl;
|
|
|
|
//write includes and namespace
|
|
|
|
UMLPackage *container = c->getUMLPackage();
|
|
if (container == logicalView)
|
|
container = NULL;
|
|
|
|
UMLPackageList includes;
|
|
findObjectsRelated(c, includes);
|
|
m_seenIncludes.clear();
|
|
//m_seenIncludes.append(logicalView);
|
|
if (includes.count()) {
|
|
UMLPackage *p;
|
|
for (UMLPackageListIt it(includes); (p = it.current()) != NULL; ++it) {
|
|
UMLClassifier *cl = dynamic_cast<UMLClassifier*>(p);
|
|
if (cl)
|
|
p = cl->getUMLPackage();
|
|
if (p != logicalView && m_seenIncludes.findRef(p) == -1 && p != container) {
|
|
cs << "using " << p->getFullyQualifiedName(".") << ";" << m_endl;
|
|
m_seenIncludes.append(p);
|
|
}
|
|
}
|
|
cs << m_endl;
|
|
}
|
|
|
|
m_container_indent = "";
|
|
|
|
if (container) {
|
|
cs << "namespace " << container->getFullyQualifiedName(".") << m_endl;
|
|
cs << "{" << m_endl << m_endl;
|
|
m_container_indent = m_indentation;
|
|
m_seenIncludes.append(container);
|
|
}
|
|
|
|
//Write class Documentation if there is somthing or if force option
|
|
if (forceDoc() || !c->getDoc().isEmpty()) {
|
|
cs << m_container_indent << "/// <summary>" << m_endl;
|
|
cs << formatDoc(c->getDoc(), m_container_indent + "/// " );
|
|
cs << m_container_indent << "/// </summary>" << m_endl ;
|
|
}
|
|
|
|
UMLClassifierList superclasses = c->getSuperClasses();
|
|
UMLAssociationList aggregations = c->getAggregations();
|
|
UMLAssociationList compositions = c->getCompositions();
|
|
UMLAssociationList realizations = c->getRealizations();
|
|
bool isInterface = c->isInterface();
|
|
m_unnamedRoles = 1;
|
|
|
|
cs << m_container_indent << "public ";
|
|
|
|
//check if it is an interface or regular class
|
|
if (isInterface) {
|
|
cs << "interface " << classname;
|
|
} else {
|
|
//check if class is abstract and / or has abstract methods
|
|
if (c->getAbstract() || c->hasAbstractOps())
|
|
cs << "abstract ";
|
|
|
|
cs << "class " << classname << (superclasses.count() > 0 ? " : ":"");
|
|
|
|
// write baseclass, ignore interfaces, write error on multiple inheritance
|
|
if (superclasses.count() > 0) {
|
|
UMLClassifier *obj;
|
|
int supers = 0;
|
|
for (obj = superclasses.first(); obj; obj = superclasses.next()) {
|
|
if (!obj->isInterface()) {
|
|
if (supers > 0) {
|
|
cs << " // AND ";
|
|
}
|
|
cs << cleanName(obj->getName());
|
|
supers++;
|
|
}
|
|
}
|
|
if (supers > 1) {
|
|
cs << m_endl << "//WARNING: C# does not support multiple inheritance but there is more than 1 superclass defined in your UML model!" << m_endl;
|
|
}
|
|
}
|
|
//check for realizations
|
|
UMLAssociationList realizations = c->getRealizations();
|
|
UMLAssociation *a;
|
|
|
|
if (!realizations.isEmpty()) {
|
|
for (a = realizations.first(); a; a = realizations.next()) {
|
|
UMLClassifier *real = (UMLClassifier*)a->getObject(Uml::B);
|
|
if(real != c) {
|
|
// write list of realizations
|
|
cs << ", " << real->getName();
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
cs << m_endl << m_container_indent << '{' << m_endl;
|
|
|
|
//associations
|
|
if (forceSections() || !aggregations.isEmpty()) {
|
|
cs << m_endl << m_container_indent << m_indentation << "#region Aggregations" << m_endl << m_endl;
|
|
writeAssociatedAttributes(aggregations, c, cs);
|
|
cs << m_endl << m_container_indent << m_indentation << "#endregion" << m_endl;
|
|
}
|
|
|
|
//compositions
|
|
if (forceSections() || !compositions.isEmpty()) {
|
|
cs << m_endl << m_container_indent << m_indentation << "#region Compositions" << m_endl << m_endl;
|
|
writeAssociatedAttributes(compositions, c, cs);
|
|
cs << m_endl << m_container_indent << m_indentation << "#endregion" << m_endl;
|
|
}
|
|
|
|
//attributes
|
|
// FIXME: C# allows Properties in interface!
|
|
if (!isInterface)
|
|
writeAttributes(c, cs);
|
|
|
|
//operations
|
|
writeOperations(c, cs);
|
|
|
|
//finish file
|
|
cs << m_endl << m_container_indent << "}" << m_endl << m_endl; // close class
|
|
|
|
if (container) {
|
|
cs << "} // end of namespace "
|
|
<< container->getFullyQualifiedName(".") << m_endl << m_endl;
|
|
}
|
|
|
|
//close files and notfiy we are done
|
|
filecs.close();
|
|
emit codeGenerated(c, true);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
// Helper Methods
|
|
|
|
void CSharpWriter::writeOperations(UMLClassifier *c, TQTextStream &cs) {
|
|
|
|
//Lists to store operations sorted by scope
|
|
UMLOperationList oppub,opprot,oppriv;
|
|
|
|
bool isInterface = c->isInterface();
|
|
bool generateErrorStub = true;
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
// write realizations (recursive)
|
|
UMLAssociationList realizations = c->getRealizations();
|
|
|
|
if (!isInterface && !realizations.isEmpty()) {
|
|
writeRealizationsRecursive(c, &realizations, cs);
|
|
}
|
|
|
|
// write public operations
|
|
if (forceSections() || !oppub.isEmpty()) {
|
|
cs << m_endl << m_container_indent << m_indentation << "#region Public methods" << m_endl << m_endl;
|
|
writeOperations(oppub,cs,isInterface,false,generateErrorStub);
|
|
cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
|
|
}
|
|
|
|
// write protected operations
|
|
if (forceSections() || !opprot.isEmpty()) {
|
|
cs << m_endl << m_container_indent << m_indentation << "#region Protected methods" << m_endl << m_endl;
|
|
writeOperations(opprot,cs,isInterface,false,generateErrorStub);
|
|
cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
|
|
}
|
|
|
|
// write private operations
|
|
if (forceSections() || !oppriv.isEmpty()) {
|
|
cs << m_endl << m_container_indent << m_indentation << "#region Private methods" << m_endl << m_endl;
|
|
writeOperations(oppriv,cs,isInterface,false,generateErrorStub);
|
|
cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
|
|
}
|
|
|
|
// write superclasses abstract methods
|
|
UMLClassifierList superclasses = c->getSuperClasses();
|
|
|
|
if (!isInterface && !c->getAbstract() && !c->hasAbstractOps()
|
|
&& superclasses.count() > 0) {
|
|
writeOverridesRecursive(&superclasses, cs);
|
|
}
|
|
|
|
}
|
|
|
|
void CSharpWriter::writeOverridesRecursive(UMLClassifierList *superclasses, TQTextStream &cs) {
|
|
// oplist for implemented abstract operations
|
|
UMLOperationList opabstract;
|
|
opabstract.setAutoDelete(false);
|
|
UMLClassifier *obj;
|
|
|
|
for (obj = superclasses->first(); obj; obj = superclasses->next()) {
|
|
if (!obj->isInterface() && obj->hasAbstractOps()) {
|
|
// collect abstract ops
|
|
UMLOperationList opl(obj->getOpList());
|
|
for (UMLOperation *op = opl.first(); op ; op = opl.next()) {
|
|
if (op->getAbstract()) {
|
|
opabstract.append(op);
|
|
}
|
|
}
|
|
|
|
// write abstract implementations
|
|
cs << m_endl << m_container_indent << m_indentation << "#region " << obj->getName() << " members" << m_endl << m_endl;
|
|
writeOperations(opabstract,cs,false,true,true);
|
|
cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
|
|
|
|
opabstract.clear();
|
|
}
|
|
// Recurse to parent superclasses
|
|
UMLClassifierList superRecursive = obj->getSuperClasses();
|
|
UMLClassifierList *superRecursivePtr =& superRecursive;
|
|
if (superRecursivePtr->count() > 0) {
|
|
writeOverridesRecursive(superRecursivePtr, cs);
|
|
}
|
|
}
|
|
}
|
|
void CSharpWriter::writeRealizationsRecursive(UMLClassifier *currentClass, UMLAssociationList *realizations, TQTextStream &cs) {
|
|
|
|
UMLAssociation *a;
|
|
for (a = realizations->first(); a; a = realizations->next()) {
|
|
|
|
// we know its a classifier if its in the list
|
|
UMLClassifier *real = (UMLClassifier*)a->getObject(Uml::B);
|
|
|
|
//FIXME: Interfaces realize themselves without this condition!?
|
|
if (real == currentClass)
|
|
continue;
|
|
|
|
// collect operations of one realization
|
|
UMLOperationList opreal = real->getOpList();
|
|
|
|
// write realizations
|
|
cs << m_endl << m_container_indent << m_indentation << "#region " << real->getName() << " members" << m_endl << m_endl;
|
|
writeOperations(opreal,cs,false,false,true);
|
|
cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
|
|
|
|
// Recurse to parent realizations
|
|
UMLAssociationList parentReal = real->getRealizations();
|
|
if (!parentReal.isEmpty()) {
|
|
writeRealizationsRecursive(real, &parentReal, cs);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CSharpWriter::writeOperations(UMLOperationList opList,
|
|
TQTextStream &cs, bool isInterface /* = false */,
|
|
bool isOverride /* = false */,
|
|
bool generateErrorStub /* = false */) {
|
|
|
|
for (UMLOperation *op=opList.first(); op ; op=opList.next()) {
|
|
UMLAttributeList atl = op->getParmList();
|
|
UMLAttribute *at;
|
|
|
|
//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();
|
|
}
|
|
|
|
//write method documentation
|
|
if (writeDoc && !isOverride)
|
|
{
|
|
cs << m_container_indent << m_indentation << "/// <summary>" << m_endl;
|
|
cs << formatDoc(op->getDoc(), m_container_indent + m_indentation + "/// ");
|
|
cs << m_container_indent << m_indentation << "/// </summary>" << m_endl;
|
|
|
|
//write parameter documentation
|
|
for (at = atl.first(); at; at = atl.next())
|
|
{
|
|
if (forceDoc() || !at->getDoc().isEmpty()) {
|
|
cs << m_container_indent << m_indentation << "/// <param name=\"" << cleanName(at->getName()) << "\">";
|
|
//removing newlines from parameter doc
|
|
cs << formatDoc(at->getDoc(), "").replace("\n", " ").remove('\r').replace(TQRegExp(" $"), "");
|
|
cs << "</param>" << m_endl;
|
|
}
|
|
}
|
|
|
|
// FIXME: "returns" should contain documentation, not type.
|
|
cs << m_container_indent << m_indentation << "/// <returns>";
|
|
if (! op->getTypeName().isEmpty()) {
|
|
cs << makeLocalTypeName(op);
|
|
}
|
|
cs << "</returns>" << m_endl;
|
|
|
|
}
|
|
|
|
// method visibility
|
|
cs << m_container_indent << m_indentation;
|
|
if (!isInterface) {
|
|
if (!isOverride) {
|
|
if (op->getAbstract()) cs << "abstract ";
|
|
cs << op->getVisibility().toString() << " ";
|
|
if (op->getStatic()) cs << "static ";
|
|
}
|
|
else {
|
|
// method overriding an abstract parent
|
|
cs << op->getVisibility().toString() << " override ";
|
|
if (op->getStatic()) cs << "static ";
|
|
}
|
|
}
|
|
|
|
// return type (unless constructor, destructor)
|
|
if (!op->isLifeOperation()) {
|
|
if (op->getTypeName().isEmpty()) {
|
|
cs << "void ";
|
|
}
|
|
else {
|
|
cs << makeLocalTypeName(op) << " ";
|
|
}
|
|
}
|
|
|
|
// method name
|
|
cs << cleanName(op->getName()) << "(";
|
|
|
|
// method parameters
|
|
int i= atl.count();
|
|
int j=0;
|
|
for (at = atl.first(); at; at = atl.next(), j++) {
|
|
|
|
cs << makeLocalTypeName(at) << " " << cleanName(at->getName());
|
|
|
|
// no initial values in C#
|
|
//<< (!(at->getInitialValue().isEmpty()) ?
|
|
// (TQString(" = ")+at->getInitialValue()) :
|
|
// TQString(""))
|
|
cs << ((j < i-1)?", ":"");
|
|
}
|
|
cs << ")";
|
|
|
|
//FIXME: how to control generation of error stub?
|
|
if (!isInterface && (!op->getAbstract() || isOverride)) {
|
|
cs << m_endl << m_container_indent << m_indentation << "{" << m_endl;
|
|
if (generateErrorStub) {
|
|
cs << m_container_indent << m_indentation << m_indentation;
|
|
cs << "throw new Exception(\"The method or operation is not implemented.\");" << m_endl;
|
|
}
|
|
cs << m_container_indent << m_indentation << "}" << m_endl;
|
|
}
|
|
else {
|
|
cs << ';' << m_endl;
|
|
}
|
|
cs << m_endl;
|
|
}
|
|
}
|
|
|
|
void CSharpWriter::writeAttributes(UMLClassifier *c, TQTextStream &cs) {
|
|
|
|
UMLAttributeList atpub, atprot, atpriv, atdefval;
|
|
atpub.setAutoDelete(false);
|
|
atprot.setAutoDelete(false);
|
|
atpriv.setAutoDelete(false);
|
|
atdefval.setAutoDelete(false);
|
|
|
|
//sort attributes by scope and see if they have a default value
|
|
UMLAttributeList atl = c->getAttributeList();
|
|
UMLAttribute *at;
|
|
|
|
for (at = atl.first(); at ; at = atl.next()) {
|
|
if (!at->getInitialValue().isEmpty())
|
|
atdefval.append(at);
|
|
switch (at->getVisibility()) {
|
|
case Uml::Visibility::Public:
|
|
atpub.append(at);
|
|
break;
|
|
case Uml::Visibility::Protected:
|
|
atprot.append(at);
|
|
break;
|
|
case Uml::Visibility::Private:
|
|
atpriv.append(at);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (forceSections() || atl.count())
|
|
cs << m_endl << m_container_indent << m_indentation << "#region Attributes" << m_endl << m_endl;
|
|
|
|
// write public attributes
|
|
if (forceSections() || atpub.count()) {
|
|
writeAttributes(atpub,cs);
|
|
}
|
|
|
|
// write protected attributes
|
|
if (forceSections() || atprot.count()) {
|
|
writeAttributes(atprot,cs);
|
|
}
|
|
|
|
// write private attributes
|
|
if (forceSections() || atpriv.count()) {
|
|
writeAttributes(atpriv,cs);
|
|
}
|
|
|
|
if (forceSections() || atl.count())
|
|
cs << m_endl << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl;
|
|
|
|
}
|
|
|
|
|
|
void CSharpWriter::writeAttributes(UMLAttributeList &atList, TQTextStream &cs) {
|
|
|
|
for (UMLAttribute *at = atList.first(); at ; at = atList.next()) {
|
|
|
|
bool asProperty = true;
|
|
if (at->getVisibility() == Uml::Visibility::Private) {
|
|
asProperty = false;
|
|
}
|
|
writeAttribute(at->getDoc(), at->getVisibility(), at->getStatic(),
|
|
makeLocalTypeName(at), at->getName(), at->getInitialValue(), asProperty, cs);
|
|
|
|
cs << m_endl;
|
|
} // end for
|
|
return;
|
|
}
|
|
|
|
void CSharpWriter::writeAssociatedAttributes(UMLAssociationList &associated, UMLClassifier *c, TQTextStream &cs) {
|
|
|
|
UMLAssociation *a;
|
|
for (a = associated.first(); a ; a = associated.next()) {
|
|
if (c != a->getObject(Uml::A)) // we need to be at the A side
|
|
continue;
|
|
|
|
UMLObject *o = a->getObject(Uml::B);
|
|
if (o == NULL) {
|
|
kError() << "composition role B object is NULL" << endl;
|
|
continue;
|
|
}
|
|
// Take name and documentaton from Role, take type name from the referenced object
|
|
TQString roleName = cleanName(a->getRoleName(Uml::B));
|
|
TQString typeName = cleanName(o->getName());
|
|
if (roleName.isEmpty()) {
|
|
roleName = TQString("UnnamedRoleB_%1").arg(m_unnamedRoles++);
|
|
}
|
|
TQString roleDoc = a->getRoleDoc(Uml::B);
|
|
|
|
//FIXME:is this simple condition enough?
|
|
if (a->getMulti(Uml::B).isEmpty() || a->getMulti(Uml::B) == "1") {
|
|
// normal attribute
|
|
writeAttribute(roleDoc, a->getVisibility(Uml::B), false, typeName, roleName, "", ( a->getVisibility(Uml::B) != Uml::Visibility::Private), cs);
|
|
} else {
|
|
// array
|
|
roleDoc += "\n(Array of " + typeName + ')';
|
|
writeAttribute(roleDoc, a->getVisibility(Uml::B), false, "ArrayList", roleName, "", ( a->getVisibility(Uml::B) != Uml::Visibility::Private), cs);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CSharpWriter::writeAttribute(TQString doc, Uml::Visibility visibility, bool isStatic, TQString typeName, TQString name, TQString initialValue, bool asProperty, TQTextStream &cs) {
|
|
|
|
if (forceDoc() || !doc.isEmpty()) {
|
|
|
|
cs << m_container_indent << m_indentation << "/// <summary>" << m_endl;
|
|
cs << formatDoc(doc, m_container_indent + m_indentation + "/// ");
|
|
cs << m_container_indent << m_indentation << "/// </summary>" << m_endl;
|
|
|
|
}
|
|
cs << m_container_indent << m_indentation;
|
|
cs << visibility.toString() << " ";
|
|
if (isStatic) cs << "static ";
|
|
|
|
//Variable type with/without namespace path
|
|
cs << typeName << " ";
|
|
|
|
cs << cleanName(name);
|
|
|
|
// FIXME: may need a GUI switch to not generate as Property?
|
|
|
|
// Generate as Property if not private
|
|
if (asProperty)
|
|
{
|
|
cs << m_endl;
|
|
cs << m_container_indent << m_indentation << "{" << m_endl;
|
|
cs << m_container_indent << m_indentation << m_indentation << "get" << m_endl;
|
|
cs << m_container_indent << m_indentation << m_indentation << "{" << m_endl;
|
|
cs << m_container_indent << m_indentation << m_indentation << m_indentation << "return m_" << cleanName(name) << ";" << m_endl;
|
|
cs << m_container_indent << m_indentation << m_indentation << "}" << m_endl;
|
|
|
|
cs << m_container_indent << m_indentation << m_indentation << "set" << m_endl;
|
|
cs << m_container_indent << m_indentation << m_indentation << "{" << m_endl;
|
|
cs << m_container_indent << m_indentation << m_indentation << m_indentation << "m_" << cleanName(name) << " = value;" << m_endl;
|
|
cs << m_container_indent << m_indentation << m_indentation << "}" << m_endl;
|
|
cs << m_container_indent << m_indentation << "}" << m_endl;
|
|
cs << m_container_indent << m_indentation << "private ";
|
|
if (isStatic) cs << "static ";
|
|
cs << typeName << " m_" << cleanName(name);
|
|
}
|
|
|
|
if (!initialValue.isEmpty())
|
|
cs << " = " << initialValue;
|
|
|
|
cs << ";" << m_endl << m_endl;
|
|
}
|
|
|
|
TQString CSharpWriter::makeLocalTypeName(UMLClassifierListItem *cl) {
|
|
UMLPackage *p = cl->getType()->getUMLPackage();
|
|
if (m_seenIncludes.findRef(p) != -1) {
|
|
return cl->getType()->getName();
|
|
}
|
|
else {
|
|
return cl->getTypeName();
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* returns "C#"
|
|
*/
|
|
Uml::Programming_Language CSharpWriter::getLanguage() {
|
|
return Uml::pl_CSharp;
|
|
}
|
|
|
|
const TQStringList CSharpWriter::reservedKeywords() const {
|
|
|
|
static TQStringList keywords;
|
|
|
|
if (keywords.isEmpty()) {
|
|
for (int i = 0; reserved_words[i]; i++)
|
|
keywords.append(reserved_words[i]);
|
|
}
|
|
|
|
return keywords;
|
|
}
|
|
|
|
#include "csharpwriter.moc"
|
|
|