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.
tdesdk/umbrello/umbrello/codegenerators/cppheadercodedocument.cpp

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"