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.
814 lines
36 KiB
814 lines
36 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) 2004-2007 *
|
|
* Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
|
|
***************************************************************************/
|
|
|
|
/* This code generated by:
|
|
* Author : thomas
|
|
* Date : Thu Aug 28 2003
|
|
*/
|
|
|
|
/**
|
|
We carve the CPP document up into 2 documents, "source" and "header".
|
|
This one represents the header portion.
|
|
The sections of each are as follows:
|
|
|
|
* header
|
|
* includes
|
|
* import statements
|
|
* class declaration
|
|
* guts of the class (e.g. field decl, accessor methods, operations, dependant classes)
|
|
*/
|
|
|
|
// own header
|
|
#include "cppheadercodedocument.h"
|
|
|
|
// qt/kde includes
|
|
#include <tqregexp.h>
|
|
#include <kdebug.h>
|
|
|
|
// local includes
|
|
#include "cppcodegenerator.h"
|
|
#include "cppcodegenerationpolicy.h"
|
|
#include "cppcodedocumentation.h"
|
|
#include "cppheadercodeaccessormethod.h"
|
|
#include "cppheadercodeoperation.h"
|
|
#include "cppheaderclassdeclarationblock.h"
|
|
#include "cppheadercodeclassfielddeclarationblock.h"
|
|
#include "../umlpackagelist.h"
|
|
#include "../package.h"
|
|
#include "../umlclassifierlistitemlist.h"
|
|
#include "../classifierlistitem.h"
|
|
#include "../enum.h"
|
|
#include "../uml.h"
|
|
|
|
// Constructors/Destructors
|
|
//
|
|
|
|
CPPHeaderCodeDocument::CPPHeaderCodeDocument ( UMLClassifier * concept )
|
|
: ClassifierCodeDocument (concept)
|
|
{
|
|
setFileExtension(".h");
|
|
|
|
//initCodeClassFields(); // this is dubious because it calls down to
|
|
// CodeGenFactory::newCodeClassField(this)
|
|
// but "this" is still in construction at that time.
|
|
|
|
// needed? I doubt it, but it feels good to do it.
|
|
classDeclCodeBlock = 0;
|
|
publicBlock = 0;
|
|
protectedBlock = 0;
|
|
privateBlock = 0;
|
|
namespaceBlock = 0;
|
|
pubConstructorBlock = 0;
|
|
protConstructorBlock = 0;
|
|
privConstructorBlock = 0;
|
|
pubOperationsBlock = 0;
|
|
privOperationsBlock = 0;
|
|
protOperationsBlock = 0;
|
|
|
|
// this will call updateContent() as well as other things that sync our document.
|
|
//synchronize();
|
|
|
|
}
|
|
|
|
CPPHeaderCodeDocument::~CPPHeaderCodeDocument ( ) {
|
|
resetTextBlocks();
|
|
}
|
|
|
|
//
|
|
// Methods
|
|
//
|
|
|
|
// Accessor methods
|
|
//
|
|
|
|
CPPHeaderClassDeclarationBlock * CPPHeaderCodeDocument::getClassDecl()
|
|
{
|
|
|
|
if(!classDeclCodeBlock) {
|
|
classDeclCodeBlock = new CPPHeaderClassDeclarationBlock (this); // was deleted before our load
|
|
classDeclCodeBlock->setTag("classDeclarationBlock");
|
|
}
|
|
return classDeclCodeBlock;
|
|
}
|
|
|
|
// Other methods
|
|
//
|
|
|
|
// Sigh. NOT optimal. The only reason that we need to have this
|
|
// is so we can create the CPPHeaderClassDeclarationBlock.
|
|
// would be better if we could create a handler interface that each
|
|
// codeblock used so all we have to do here is add the handler
|
|
void CPPHeaderCodeDocument::loadChildTextBlocksFromNode ( TQDomElement & root)
|
|
{
|
|
|
|
TQDomNode tnode = root.firstChild();
|
|
TQDomElement telement = tnode.toElement();
|
|
bool loadCheckForChildrenOK = false;
|
|
while( !telement.isNull() ) {
|
|
TQString nodeName = telement.tagName();
|
|
|
|
if( nodeName == "textblocks" ) {
|
|
|
|
TQDomNode node = telement.firstChild();
|
|
TQDomElement element = node.toElement();
|
|
|
|
// if there is nothing to begin with, then we don't worry about it
|
|
loadCheckForChildrenOK = element.isNull() ? true : false;
|
|
|
|
while( !element.isNull() ) {
|
|
TQString name = element.tagName();
|
|
|
|
if( name == "codecomment" ) {
|
|
CodeComment * block = new CPPCodeDocumentation(this);
|
|
block->loadFromXMI(element);
|
|
if(!addTextBlock(block))
|
|
{
|
|
kError()<<"Unable to add codeComment to :"<<this<<endl;
|
|
block->deleteLater();
|
|
} else
|
|
loadCheckForChildrenOK= true;
|
|
} else
|
|
if( name == "codeaccessormethod" ||
|
|
name == "ccfdeclarationcodeblock"
|
|
) {
|
|
TQString acctag = element.attribute("tag","");
|
|
// search for our method in the
|
|
TextBlock * tb = findCodeClassFieldTextBlockByTag(acctag);
|
|
if(!tb || !addTextBlock(tb))
|
|
{
|
|
kError()<<"Unable to add codeclassfield child method to:"<<this<<endl;
|
|
// DON'T delete
|
|
} else
|
|
loadCheckForChildrenOK= true;
|
|
|
|
} else
|
|
if( name == "codeblock" ) {
|
|
CodeBlock * block = newCodeBlock();
|
|
block->loadFromXMI(element);
|
|
if(!addTextBlock(block))
|
|
{
|
|
kError()<<"Unable to add codeBlock to :"<<this<<endl;
|
|
block->deleteLater();
|
|
} else
|
|
loadCheckForChildrenOK= true;
|
|
} else
|
|
if( name == "codeblockwithcomments" ) {
|
|
CodeBlockWithComments * block = newCodeBlockWithComments();
|
|
block->loadFromXMI(element);
|
|
if(!addTextBlock(block))
|
|
{
|
|
kError()<<"Unable to add codeBlockwithcomments to:"<<this<<endl;
|
|
block->deleteLater();
|
|
} else
|
|
loadCheckForChildrenOK= true;
|
|
} else
|
|
if( name == "header" ) {
|
|
// do nothing.. this is treated elsewhere
|
|
} else
|
|
if( name == "hierarchicalcodeblock" ) {
|
|
HierarchicalCodeBlock * block = newHierarchicalCodeBlock();
|
|
block->loadFromXMI(element);
|
|
if(!addTextBlock(block))
|
|
{
|
|
kError()<<"Unable to add hierarchicalcodeBlock to:"<<this<<endl;
|
|
block->deleteLater();
|
|
} else
|
|
loadCheckForChildrenOK= true;
|
|
} else
|
|
if( name == "codeoperation" ) {
|
|
// find the code operation by id
|
|
TQString id = element.attribute("parent_id","-1");
|
|
UMLObject * obj = UMLApp::app()->getDocument()->findObjectById(STR2ID(id));
|
|
UMLOperation * op = dynamic_cast<UMLOperation*>(obj);
|
|
if(op) {
|
|
CodeOperation * block = new CPPHeaderCodeOperation(this, op);
|
|
block->loadFromXMI(element);
|
|
if(addTextBlock(block))
|
|
loadCheckForChildrenOK= true;
|
|
else
|
|
{
|
|
kError()<<"Unable to add codeoperation to:"<<this<<endl;
|
|
block->deleteLater();
|
|
}
|
|
} else
|
|
kError()<<"Unable to find operation create codeoperation for:"<<this<<endl;
|
|
}
|
|
else
|
|
if( name == "cppheaderclassdeclarationblock" )
|
|
{
|
|
CPPHeaderClassDeclarationBlock * block = getClassDecl();
|
|
block->loadFromXMI(element);
|
|
// normally this would be populated by the following syncToparent
|
|
// call, but we cant wait for it, so lets just do it now.
|
|
namespaceBlock = getHierarchicalCodeBlock("namespace", "Namespace", 0);
|
|
|
|
if(!namespaceBlock || !namespaceBlock->addTextBlock(block))
|
|
{
|
|
kError()<<"Error:cant add class declaration codeblock"<<endl;
|
|
// DON'T delete/release block
|
|
// block->release();
|
|
} else
|
|
loadCheckForChildrenOK= true;
|
|
|
|
}
|
|
// only needed for extreme debugging conditions (E.g. making new codeclassdocument loader)
|
|
//else
|
|
//kDebug()<<" LoadFromXMI: Got strange tag in text block stack:"<<name<<", ignorning"<<endl;
|
|
|
|
node = element.nextSibling();
|
|
element = node.toElement();
|
|
}
|
|
break;
|
|
}
|
|
|
|
tnode = telement.nextSibling();
|
|
telement = tnode.toElement();
|
|
}
|
|
|
|
if(!loadCheckForChildrenOK)
|
|
{
|
|
CodeDocument * test = dynamic_cast<CodeDocument*>(this);
|
|
if(test)
|
|
{
|
|
kWarning()<<" loadChildBlocks : unable to initialize any child blocks in doc: "<<test->getFileName()<<" "<<this<<endl;
|
|
} else {
|
|
HierarchicalCodeBlock * hb = dynamic_cast<HierarchicalCodeBlock*>(this);
|
|
if(hb)
|
|
kWarning()<<" loadChildBlocks : unable to initialize any child blocks in Hblock: "<<hb->getTag()<<" "<<this<<endl;
|
|
else
|
|
kDebug()<<" loadChildBlocks : unable to initialize any child blocks in UNKNOWN OBJ:"<<this<<endl;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void CPPHeaderCodeDocument::resetTextBlocks()
|
|
{
|
|
|
|
// all special pointers need to be zero'd out.
|
|
classDeclCodeBlock = 0;
|
|
publicBlock = 0;
|
|
protectedBlock = 0;
|
|
privateBlock = 0;
|
|
namespaceBlock = 0;
|
|
pubConstructorBlock = 0;
|
|
protConstructorBlock = 0;
|
|
privConstructorBlock = 0;
|
|
pubOperationsBlock = 0;
|
|
privOperationsBlock = 0;
|
|
protOperationsBlock = 0;
|
|
|
|
// now do the traditional release of child text blocks
|
|
ClassifierCodeDocument::resetTextBlocks();
|
|
|
|
}
|
|
|
|
/**
|
|
* @param op
|
|
*/
|
|
// in the vannilla version, we just tack all operations on the end
|
|
// of the document
|
|
bool CPPHeaderCodeDocument::addCodeOperation (CodeOperation * op )
|
|
{
|
|
Uml::Visibility scope = op->getParentOperation()->getVisibility();
|
|
if(!op->getParentOperation()->isLifeOperation())
|
|
{
|
|
switch (scope) {
|
|
default:
|
|
case Uml::Visibility::Public:
|
|
return pubOperationsBlock->addTextBlock(op);
|
|
break;
|
|
case Uml::Visibility::Protected:
|
|
return protOperationsBlock->addTextBlock(op);
|
|
break;
|
|
case Uml::Visibility::Private:
|
|
return privOperationsBlock->addTextBlock(op);
|
|
break;
|
|
}
|
|
} else {
|
|
switch (scope) {
|
|
default:
|
|
case Uml::Visibility::Public:
|
|
return pubConstructorBlock->addTextBlock(op);
|
|
break;
|
|
case Uml::Visibility::Protected:
|
|
return protConstructorBlock->addTextBlock(op);
|
|
break;
|
|
case Uml::Visibility::Private:
|
|
return privConstructorBlock->addTextBlock(op);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Save the XMI representation of this object
|
|
* @return bool status of save
|
|
*/
|
|
/*
|
|
void CPPHeaderCodeDocument::saveToXMI ( TQDomDocument & doc, TQDomElement & root )
|
|
{
|
|
TQDomElement docElement = doc.createElement( "" );
|
|
|
|
setAttributesOnNode(doc, docElement);
|
|
|
|
root.appendChild( docElement );
|
|
}
|
|
*/
|
|
|
|
// This method will cause the class to rebuild its text representation.
|
|
// based on the parent classifier object.
|
|
// For any situation in which this is called, we are either building the code
|
|
// document up, or replacing/regenerating the existing auto-generated parts. As
|
|
// such, we will want to insert everything we resonablely will want
|
|
// during creation. We can set various parts of the document (esp. the
|
|
// comments) to appear or not, as needed.
|
|
void CPPHeaderCodeDocument::updateContent( )
|
|
{
|
|
// Gather info on the various fields and parent objects of this class...
|
|
UMLClassifier * c = getParentClassifier();
|
|
CodeGenPolicyExt *pe = UMLApp::app()->getPolicyExt();
|
|
CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe);
|
|
|
|
// first, set the global flag on whether or not to show classfield info
|
|
CodeClassFieldList * cfList = getCodeClassFieldList();
|
|
for(CodeClassField * field = cfList->first(); field; field = cfList->next())
|
|
field->setWriteOutMethods(policy->getAutoGenerateAccessors());
|
|
|
|
// attribute-based ClassFields
|
|
// we do it this way to have the static fields sorted out from regular ones
|
|
CodeClassFieldList staticPublicAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Public );
|
|
CodeClassFieldList publicAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Public );
|
|
CodeClassFieldList staticProtectedAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Protected );
|
|
CodeClassFieldList protectedAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Protected );
|
|
CodeClassFieldList staticPrivateAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Private );
|
|
CodeClassFieldList privateAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Private);
|
|
|
|
// association-based ClassFields
|
|
// don't care if they are static or not..all are lumped together
|
|
CodeClassFieldList publicPlainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation , Uml::Visibility::Public);
|
|
CodeClassFieldList publicAggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation, Uml::Visibility::Public);
|
|
CodeClassFieldList publicCompositionClassFields = getSpecificClassFields ( CodeClassField::Composition, Uml::Visibility::Public );
|
|
|
|
CodeClassFieldList protPlainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation , Uml::Visibility::Protected);
|
|
CodeClassFieldList protAggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation, Uml::Visibility::Protected);
|
|
CodeClassFieldList protCompositionClassFields = getSpecificClassFields ( CodeClassField::Composition, Uml::Visibility::Protected);
|
|
|
|
CodeClassFieldList privPlainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation , Uml::Visibility::Private);
|
|
CodeClassFieldList privAggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation, Uml::Visibility::Private);
|
|
CodeClassFieldList privCompositionClassFields = getSpecificClassFields ( CodeClassField::Composition, Uml::Visibility::Private);
|
|
|
|
bool hasOperationMethods = c->getOpList().last() ? true : false;
|
|
bool hasNamespace = false;
|
|
bool isEnumeration = false;
|
|
bool isInterface = parentIsInterface();
|
|
bool hasclassFields = hasClassFields();
|
|
bool forcedoc = UMLApp::app()->getCommonPolicy()->getCodeVerboseDocumentComments();
|
|
TQString endLine = UMLApp::app()->getCommonPolicy()->getNewLineEndingChars();
|
|
|
|
UMLClassifierList superclasses = c->findSuperClassConcepts();
|
|
|
|
|
|
// START GENERATING CODE/TEXT BLOCKS and COMMENTS FOR THE DOCUMENT
|
|
//
|
|
|
|
// Write the hash define stuff to prevent multiple parsing/inclusion of header
|
|
TQString cppClassName = CodeGenerator::cleanName(c->getName());
|
|
TQString hashDefine = CodeGenerator::cleanName(c->getName().upper().simplifyWhiteSpace());
|
|
TQString defText = "#ifndef "+hashDefine + "_H"+ endLine + "#define "+ hashDefine + "_H";
|
|
addOrUpdateTaggedCodeBlockWithComments("hashDefBlock", defText, "", 0, false);
|
|
|
|
// INCLUDE CODEBLOCK
|
|
//
|
|
// Q: Why all utils? Isnt just List and Vector the only classes we are using?
|
|
// A: doesn't matter at all; its more readable to just include '*' and cpp compilers
|
|
// don't slow down or anything. (TZ)
|
|
TQString includeStatement = "";
|
|
bool stringGlobal = policy->stringIncludeIsGlobal();
|
|
TQString sStartBrak = stringGlobal ? "<" : "\"";
|
|
TQString sEndBrak = stringGlobal ? ">" : "\"";
|
|
includeStatement.append("#include "+sStartBrak+policy->getStringClassNameInclude()+sEndBrak+endLine);
|
|
if ( hasObjectVectorClassFields() )
|
|
{
|
|
bool vecGlobal = policy->vectorIncludeIsGlobal();
|
|
TQString vStartBrak = vecGlobal ? "<" : "\"";
|
|
TQString vEndBrak = vecGlobal ? ">" : "\"";
|
|
TQString value ="#include "+vStartBrak+policy->getVectorClassNameInclude()+vEndBrak;
|
|
includeStatement.append(value+endLine);
|
|
}
|
|
|
|
//only include classes in a different package from this class
|
|
UMLPackageList includes;
|
|
TQMap<UMLPackage *,TQString> packageMap; // so we don't repeat packages
|
|
|
|
CodeGenerator::findObjectsRelated(c,includes);
|
|
for(UMLPackage *con = includes.first(); con ; con = includes.next())
|
|
if (con->getBaseType() != Uml::ot_Datatype && !packageMap.contains(con))
|
|
{
|
|
packageMap.insert(con,con->getPackage());
|
|
if(con != getParentClassifier())
|
|
includeStatement.append("#include \""+CodeGenerator::cleanName(con->getName().lower())+".h\""+endLine);
|
|
}
|
|
// now, add/update the includes codeblock
|
|
CodeBlockWithComments * inclBlock = addOrUpdateTaggedCodeBlockWithComments("includes", includeStatement, TQString(), 0, false);
|
|
if(includeStatement.isEmpty() && inclBlock->getContentType() == CodeBlock::AutoGenerated)
|
|
inclBlock->setWriteOutText(false);
|
|
else
|
|
inclBlock->setWriteOutText(true);
|
|
|
|
// Using
|
|
TQString usingStatement;
|
|
for(UMLClassifier *classifier = superclasses.first(); classifier ; classifier = superclasses.next()) {
|
|
if(classifier->getPackage()!=c->getPackage() && !classifier->getPackage().isEmpty()) {
|
|
usingStatement.append("using "+CodeGenerator::cleanName(c->getPackage())+"::"+cleanName(c->getName())+';'+endLine);
|
|
}
|
|
}
|
|
CodeBlockWithComments * usingBlock = addOrUpdateTaggedCodeBlockWithComments("using", usingStatement, "", 0, false);
|
|
if(usingStatement.isEmpty() && usingBlock->getContentType() == CodeBlock::AutoGenerated)
|
|
usingBlock->setWriteOutText(false);
|
|
else
|
|
usingBlock->setWriteOutText(true);
|
|
|
|
// namespace
|
|
// This needs special treatment. We cant use "nowriteouttext" for this, as
|
|
// that will prevent the class declaration from being written. Instead, we
|
|
// check if "hasNamspace" is true or not, and then indent the remaining code
|
|
// appropriately as well as set the start/end text of this namespace block.
|
|
if (c->getUMLPackage() && policy->getPackageIsNamespace())
|
|
hasNamespace = true;
|
|
else
|
|
hasNamespace = false;
|
|
|
|
// set start/end text of namespace block
|
|
namespaceBlock = getHierarchicalCodeBlock("namespace", "Namespace", 0);
|
|
if(hasNamespace) {
|
|
UMLPackageList pkgList = c->getPackages();
|
|
TQString pkgs;
|
|
UMLPackage *pkg;
|
|
for (pkg = pkgList.first(); pkg != NULL; pkg = pkgList.next()) {
|
|
pkgs += "namespace " + CodeGenerator::cleanName(pkg->getName()) + " { ";
|
|
}
|
|
namespaceBlock->setStartText(pkgs);
|
|
TQString closingBraces;
|
|
for (pkg = pkgList.first(); pkg != NULL; pkg = pkgList.next()) {
|
|
closingBraces += "} ";
|
|
}
|
|
namespaceBlock->setEndText(closingBraces);
|
|
namespaceBlock->getComment()->setWriteOutText(true);
|
|
} else {
|
|
namespaceBlock->setStartText("");
|
|
namespaceBlock->setEndText("");
|
|
namespaceBlock->getComment()->setWriteOutText(false);
|
|
}
|
|
|
|
// Enum types for include
|
|
if (!isInterface) {
|
|
TQString enumStatement;
|
|
TQString indent = UMLApp::app()->getCommonPolicy()->getIndentation();
|
|
UMLEnum* e = dynamic_cast<UMLEnum*>(c);
|
|
if (e) {
|
|
enumStatement.append(indent + "enum " + cppClassName + " {" + endLine);
|
|
|
|
// populate
|
|
UMLClassifierListItemList ell = e->getFilteredList(Uml::ot_EnumLiteral);
|
|
for (UMLClassifierListItem *el=ell.first(); el ; ) {
|
|
enumStatement.append(indent+indent);
|
|
enumStatement.append(CodeGenerator::cleanName(el->getName()));
|
|
if ((el=ell.next()) != 0)
|
|
enumStatement.append(", "+endLine);
|
|
else
|
|
break;
|
|
enumStatement.append(endLine);
|
|
}
|
|
enumStatement.append(indent+"};");
|
|
isEnumeration = true;
|
|
}
|
|
namespaceBlock->addOrUpdateTaggedCodeBlockWithComments("enums", enumStatement, "", 0, false);
|
|
}
|
|
|
|
// CLASS DECLARATION BLOCK
|
|
//
|
|
|
|
// add the class declaration block to the namespace block.
|
|
CPPHeaderClassDeclarationBlock * myClassDeclCodeBlock = getClassDecl();
|
|
namespaceBlock->addTextBlock(myClassDeclCodeBlock); // note: wont add if already present
|
|
|
|
// Is this really true?? hmm..
|
|
if(isEnumeration)
|
|
myClassDeclCodeBlock->setWriteOutText(false); // not written out IF its an enumeration class
|
|
else
|
|
myClassDeclCodeBlock->setWriteOutText(true);
|
|
|
|
//
|
|
// Main Sub-Blocks
|
|
//
|
|
|
|
// declare public, protected and private methods, attributes (fields).
|
|
// set the start text ONLY if this is the first time we created the objects.
|
|
bool createdPublicBlock = publicBlock == 0 ? true : false;
|
|
publicBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("publicBlock","Public stuff",0);
|
|
if (createdPublicBlock)
|
|
publicBlock->setStartText("public:");
|
|
|
|
bool createdProtBlock = protectedBlock == 0 ? true : false;
|
|
protectedBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("protectedBlock","Protected stuff",0);
|
|
if(createdProtBlock)
|
|
protectedBlock->setStartText("protected:");
|
|
|
|
bool createdPrivBlock = privateBlock == 0 ? true : false;
|
|
privateBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("privateBlock","Private stuff",0);
|
|
if(createdPrivBlock)
|
|
privateBlock->setStartText("private:");
|
|
|
|
//
|
|
// * CLASS FIELD declaration section
|
|
//
|
|
|
|
// setup/get/create the field declaration code block
|
|
//
|
|
|
|
// public fields: Update the comment: we only set comment to appear under the following conditions
|
|
HierarchicalCodeBlock * publicFieldDeclBlock = publicBlock->getHierarchicalCodeBlock("publicFieldsDecl", "Fields", 1);
|
|
CodeComment * pubFcomment = publicFieldDeclBlock->getComment();
|
|
if (!forcedoc && !hasclassFields )
|
|
pubFcomment->setWriteOutText(false);
|
|
else
|
|
pubFcomment->setWriteOutText(true);
|
|
|
|
// protected fields: Update the comment: we only set comment to appear under the following conditions
|
|
HierarchicalCodeBlock * protectedFieldDeclBlock = protectedBlock->getHierarchicalCodeBlock("protectedFieldsDecl", "Fields", 1);
|
|
CodeComment * protFcomment = protectedFieldDeclBlock->getComment();
|
|
if (!forcedoc && !hasclassFields )
|
|
protFcomment->setWriteOutText(false);
|
|
else
|
|
protFcomment->setWriteOutText(true);
|
|
|
|
// private fields: Update the comment: we only set comment to appear under the following conditions
|
|
HierarchicalCodeBlock * privateFieldDeclBlock = privateBlock->getHierarchicalCodeBlock("privateFieldsDecl", "Fields", 1);
|
|
CodeComment * privFcomment = privateFieldDeclBlock->getComment();
|
|
if (!forcedoc && !hasclassFields )
|
|
privFcomment->setWriteOutText(false);
|
|
else
|
|
privFcomment->setWriteOutText(true);
|
|
|
|
|
|
// now actually declare the fields within the appropriate HCodeBlock
|
|
//
|
|
|
|
// public
|
|
declareClassFields(staticPublicAttribClassFields, publicFieldDeclBlock);
|
|
declareClassFields(publicAttribClassFields, publicFieldDeclBlock);
|
|
declareClassFields(publicPlainAssocClassFields, publicFieldDeclBlock);
|
|
declareClassFields(publicAggregationClassFields, publicFieldDeclBlock);
|
|
declareClassFields(publicCompositionClassFields, publicFieldDeclBlock);
|
|
|
|
// protected
|
|
declareClassFields(staticProtectedAttribClassFields, protectedFieldDeclBlock);
|
|
declareClassFields(protectedAttribClassFields, protectedFieldDeclBlock);
|
|
declareClassFields(protPlainAssocClassFields, protectedFieldDeclBlock);
|
|
declareClassFields(protAggregationClassFields, protectedFieldDeclBlock);
|
|
declareClassFields(protCompositionClassFields, protectedFieldDeclBlock);
|
|
|
|
// private
|
|
declareClassFields(staticPrivateAttribClassFields, privateFieldDeclBlock);
|
|
declareClassFields(privateAttribClassFields, privateFieldDeclBlock);
|
|
declareClassFields(privPlainAssocClassFields, privateFieldDeclBlock);
|
|
declareClassFields(privAggregationClassFields, privateFieldDeclBlock);
|
|
declareClassFields(privCompositionClassFields, privateFieldDeclBlock);
|
|
|
|
//
|
|
// METHODS section
|
|
//
|
|
|
|
// get/create the method codeblock
|
|
|
|
// public methods
|
|
HierarchicalCodeBlock * pubMethodsBlock = publicBlock->getHierarchicalCodeBlock("pubMethodsBlock", "", 1);
|
|
CodeComment * pubMethodsComment = pubMethodsBlock->getComment();
|
|
// set conditions for showing this comment
|
|
if (!forcedoc && !hasclassFields && !hasOperationMethods)
|
|
pubMethodsComment->setWriteOutText(false);
|
|
else
|
|
pubMethodsComment->setWriteOutText(true);
|
|
|
|
// protected methods
|
|
HierarchicalCodeBlock * protMethodsBlock = protectedBlock->getHierarchicalCodeBlock("protMethodsBlock", "", 1);
|
|
CodeComment * protMethodsComment = protMethodsBlock->getComment();
|
|
// set conditions for showing this comment
|
|
if (!forcedoc && !hasclassFields && !hasOperationMethods)
|
|
protMethodsComment->setWriteOutText(false);
|
|
else
|
|
protMethodsComment->setWriteOutText(true);
|
|
|
|
// private methods
|
|
HierarchicalCodeBlock * privMethodsBlock = privateBlock->getHierarchicalCodeBlock("privMethodsBlock", "", 1);
|
|
CodeComment * privMethodsComment = privMethodsBlock->getComment();
|
|
// set conditions for showing this comment
|
|
if (!forcedoc && !hasclassFields && !hasOperationMethods)
|
|
privMethodsComment->setWriteOutText(false);
|
|
else
|
|
privMethodsComment->setWriteOutText(true);
|
|
|
|
|
|
// METHODS sub-section : constructor methods
|
|
//
|
|
CodeGenerationPolicy *pol = UMLApp::app()->getCommonPolicy();
|
|
|
|
// setup/get/create the constructor codeblocks
|
|
|
|
// public
|
|
pubConstructorBlock = pubMethodsBlock->getHierarchicalCodeBlock("constructionMethods", "Constructors", 1);
|
|
// special condiions for showing comment: only when autogenerateding empty constructors
|
|
// Although, we *should* check for other constructor methods too
|
|
CodeComment * pubConstComment = pubConstructorBlock->getComment();
|
|
if (!forcedoc && (isInterface || !pol->getAutoGenerateConstructors()))
|
|
pubConstComment->setWriteOutText(false);
|
|
else
|
|
pubConstComment->setWriteOutText(true);
|
|
|
|
// protected
|
|
protConstructorBlock = protMethodsBlock->getHierarchicalCodeBlock("constructionMethods", "Constructors", 1);
|
|
// special condiions for showing comment: only when autogenerateding empty constructors
|
|
// Although, we *should* check for other constructor methods too
|
|
CodeComment * protConstComment = protConstructorBlock->getComment();
|
|
if (!forcedoc && (isInterface || !pol->getAutoGenerateConstructors()))
|
|
protConstComment->setWriteOutText(false);
|
|
else
|
|
protConstComment->setWriteOutText(true);
|
|
|
|
// private
|
|
privConstructorBlock = privMethodsBlock->getHierarchicalCodeBlock("constructionMethods", "Constructors", 1);
|
|
// special condiions for showing comment: only when autogenerateding empty constructors
|
|
// Although, we *should* check for other constructor methods too
|
|
CodeComment * privConstComment = privConstructorBlock->getComment();
|
|
if (!forcedoc && (isInterface || !pol->getAutoGenerateConstructors()))
|
|
privConstComment->setWriteOutText(false);
|
|
else
|
|
privConstComment->setWriteOutText(true);
|
|
|
|
// add/get the empty constructor. I guess since there is no
|
|
// meta-data to state what the scope of this method is, we will make it
|
|
// "public" as a default. This might present problems if the user wants
|
|
// to move the block into the "private" or "protected" blocks.
|
|
TQString emptyConstStatement = cppClassName + " ( ) { }";
|
|
|
|
// search for this first in the entire document. IF not present, put
|
|
// it in the public constructor method block
|
|
TextBlock * emptyConstTb = findTextBlockByTag("emptyconstructor", true);
|
|
CodeBlockWithComments * emptyConstBlock = dynamic_cast<CodeBlockWithComments*>(emptyConstTb);
|
|
if(!emptyConstBlock)
|
|
emptyConstBlock = pubConstructorBlock->addOrUpdateTaggedCodeBlockWithComments("emptyconstructor", emptyConstStatement, "Empty Constructor", 1, false);
|
|
|
|
// Now, as an additional condition we only show the empty constructor block
|
|
// IF it was desired to be shown
|
|
if(!isInterface && pol->getAutoGenerateConstructors())
|
|
emptyConstBlock->setWriteOutText(true);
|
|
else
|
|
emptyConstBlock->setWriteOutText(false);
|
|
|
|
|
|
// METHODS subsection : ACCESSOR METHODS
|
|
//
|
|
|
|
// get/create the accessor codeblock
|
|
|
|
// public
|
|
HierarchicalCodeBlock * pubAccessorBlock = pubMethodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1);
|
|
// set conditions for showing section comment
|
|
CodeComment * pubAccessComment = pubAccessorBlock->getComment();
|
|
if (!forcedoc && !hasclassFields)
|
|
pubAccessComment->setWriteOutText(false);
|
|
else
|
|
pubAccessComment->setWriteOutText(true);
|
|
|
|
// protected
|
|
HierarchicalCodeBlock * protAccessorBlock = protMethodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1);
|
|
// set conditions for showing section comment
|
|
CodeComment * protAccessComment = protAccessorBlock->getComment();
|
|
if (!forcedoc && !hasclassFields)
|
|
protAccessComment->setWriteOutText(false);
|
|
else
|
|
protAccessComment->setWriteOutText(true);
|
|
|
|
// private
|
|
HierarchicalCodeBlock * privAccessorBlock = privMethodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1);
|
|
// set conditions for showing section comment
|
|
CodeComment * privAccessComment = privAccessorBlock->getComment();
|
|
// We've to copy the private accessorMethods to the public block
|
|
if (!forcedoc && !hasclassFields)
|
|
privAccessComment->setWriteOutText(false);
|
|
else
|
|
privAccessComment->setWriteOutText(true);
|
|
|
|
// now, 2 sub-sub sections in accessor block
|
|
// add/update accessor methods for attributes
|
|
HierarchicalCodeBlock * pubStaticAccessors = pubAccessorBlock->getHierarchicalCodeBlock("pubStaticAccessorMethods", "", 1);
|
|
HierarchicalCodeBlock * pubRegularAccessors = pubAccessorBlock->getHierarchicalCodeBlock("pubRegularAccessorMethods", "", 1);
|
|
pubStaticAccessors->getComment()->setWriteOutText(false); // never write block comment
|
|
pubRegularAccessors->getComment()->setWriteOutText(false); // never write block comment
|
|
|
|
HierarchicalCodeBlock * protStaticAccessors = protAccessorBlock->getHierarchicalCodeBlock("protStaticAccessorMethods", "", 1);
|
|
HierarchicalCodeBlock * protRegularAccessors = protAccessorBlock->getHierarchicalCodeBlock("protRegularAccessorMethods", "", 1);
|
|
protStaticAccessors->getComment()->setWriteOutText(false); // never write block comment
|
|
protRegularAccessors->getComment()->setWriteOutText(false); // never write block comment
|
|
|
|
HierarchicalCodeBlock * privStaticAccessors = privAccessorBlock->getHierarchicalCodeBlock("privStaticAccessorMethods", "", 1);
|
|
HierarchicalCodeBlock * privRegularAccessors = privAccessorBlock->getHierarchicalCodeBlock("privRegularAccessorMethods", "", 1);
|
|
privStaticAccessors->getComment()->setWriteOutText(false); // never write block comment
|
|
privRegularAccessors->getComment()->setWriteOutText(false); // never write block comment
|
|
|
|
// now add in accessors as appropriate
|
|
|
|
// public stuff
|
|
pubStaticAccessors->addCodeClassFieldMethods(staticPublicAttribClassFields);
|
|
pubRegularAccessors->addCodeClassFieldMethods(publicAttribClassFields);
|
|
|
|
// generate accessors as public
|
|
if (policy && policy->getAccessorsArePublic())
|
|
{
|
|
pubRegularAccessors->addCodeClassFieldMethods(privateAttribClassFields);
|
|
pubRegularAccessors->addCodeClassFieldMethods(protectedAttribClassFields);
|
|
}
|
|
|
|
pubRegularAccessors->addCodeClassFieldMethods(publicPlainAssocClassFields);
|
|
pubRegularAccessors->addCodeClassFieldMethods(publicAggregationClassFields);
|
|
pubRegularAccessors->addCodeClassFieldMethods(publicCompositionClassFields);
|
|
|
|
// protected stuff
|
|
protStaticAccessors->addCodeClassFieldMethods(staticProtectedAttribClassFields);
|
|
|
|
// accessors are public so we don't have to create it here
|
|
if (policy && !policy->getAccessorsArePublic())
|
|
protRegularAccessors->addCodeClassFieldMethods(protectedAttribClassFields);
|
|
|
|
protRegularAccessors->addCodeClassFieldMethods(protPlainAssocClassFields);
|
|
protRegularAccessors->addCodeClassFieldMethods(protAggregationClassFields);
|
|
protRegularAccessors->addCodeClassFieldMethods(protCompositionClassFields);
|
|
|
|
// private stuff
|
|
privStaticAccessors->addCodeClassFieldMethods(staticPrivateAttribClassFields);
|
|
|
|
// accessors are public so we don't have to create it here
|
|
if (policy && !policy->getAccessorsArePublic())
|
|
privRegularAccessors->addCodeClassFieldMethods(privateAttribClassFields);
|
|
|
|
privRegularAccessors->addCodeClassFieldMethods(privPlainAssocClassFields);
|
|
privRegularAccessors->addCodeClassFieldMethods(privAggregationClassFields);
|
|
privRegularAccessors->addCodeClassFieldMethods(privCompositionClassFields);
|
|
|
|
|
|
// METHODS subsection : Operation methods (e.g. methods derive from operations but which arent constructors)
|
|
//
|
|
|
|
// setup/get/create the operations codeblock
|
|
|
|
// public
|
|
pubOperationsBlock = pubMethodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1);
|
|
// set conditions for showing section comment
|
|
CodeComment * pubOcomment = pubOperationsBlock->getComment();
|
|
if (!forcedoc && !hasOperationMethods )
|
|
pubOcomment->setWriteOutText(false);
|
|
else
|
|
pubOcomment->setWriteOutText(true);
|
|
|
|
//protected
|
|
protOperationsBlock = protMethodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1);
|
|
// set conditions for showing section comment
|
|
CodeComment * protOcomment = protOperationsBlock->getComment();
|
|
if (!forcedoc && !hasOperationMethods )
|
|
protOcomment->setWriteOutText(false);
|
|
else
|
|
protOcomment->setWriteOutText(true);
|
|
|
|
//private
|
|
privOperationsBlock = privMethodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1);
|
|
// set conditions for showing section comment
|
|
CodeComment * privOcomment = privOperationsBlock->getComment();
|
|
if (!forcedoc && !hasOperationMethods )
|
|
privOcomment->setWriteOutText(false);
|
|
else
|
|
privOcomment->setWriteOutText(true);
|
|
|
|
// Operations
|
|
//
|
|
// nothing to do here.. "updateOperations" in parent class puts things
|
|
// in the right place using the "addCodeOperation" method we defined in this class
|
|
|
|
// FINISH up with hash def block close
|
|
TQString defTextEnd = "#endif //"+hashDefine + "_H";
|
|
addOrUpdateTaggedCodeBlockWithComments("hashDefBlockEnd", defTextEnd, "", 0, false);
|
|
|
|
}
|
|
|
|
|
|
#include "cppheadercodedocument.moc"
|