void RefactoringAssistant::addClassifier( UMLClassifier *classifier, QListViewItem *parent, bool addSuper, bool addSub, bool recurse)
{
    QListViewItem *classifierItem, *item;
    if( parent )
    {
        classifierItem = parent;
    }
    else
    {
        classifierItem= new KListViewItem( this, classifier->getName() );
        m_umlObjectMap[classifierItem] = classifier;
    }

    connect( classifier, SIGNAL( modified() ), this, SLOT( umlObjectModified() ) );

    UMLClassifier *klass = dynamic_cast<UMLClassifier*>(classifier);
    if( klass )
    {// only Classes have attributes...
        connect( classifier, SIGNAL(attributeAdded(UMLClassifierListItem*)),
                 this, SLOT(attributeAdded(UMLClassifierListItem*)));
        connect( classifier, SIGNAL(attributeRemoved(UMLClassifierListItem*)),
                 this, SLOT(attributeRemoved(UMLClassifierListItem*)));

        QListViewItem *attsFolder = new KListViewItem( classifierItem, i18n("Attributes"), "attributes" );
        attsFolder->setPixmap(0,SmallIcon("folder_green_open"));
        attsFolder->setExpandable( true );
        UMLAttributeList atts = klass->getAttributeList();
        for( UMLAttribute *att = atts.first(); att; att = atts.next() )
        {
            attributeAdded( att );
        }

    }

    // add operations
    connect( classifier, SIGNAL(operationAdded(UMLClassifierListItem*)),
             this, SLOT(operationAdded(UMLClassifierListItem*)));
    connect( classifier, SIGNAL(operationRemoved(UMLClassifierListItem*)),
             this, SLOT(operationRemoved(UMLClassifierListItem*)));

    QListViewItem *opsFolder = new KListViewItem( classifierItem, i18n("Operations"), "operations" );
    opsFolder->setPixmap(0,SmallIcon("folder_blue_open"));
    opsFolder->setExpandable( true );
    UMLOperationList ops(classifier->getOpList());
    for( UMLOperation *op = ops.first(); op ; op = ops.next() )
    {
        operationAdded( op );
    }

    //if add parents
    if(addSuper)
    {
        QListViewItem *superFolder = new KListViewItem( classifierItem, i18n("Base Classifiers") );
        superFolder->setExpandable( true );
        UMLClassifierList super = classifier->findSuperClassConcepts();
        for( UMLClassifier *cl = super.first(); cl ; cl = super.next() )
        {
            item = new KListViewItem( superFolder, cl->getName() );
            item->setPixmap(0,m_pixmaps.Generalization);
            item->setExpandable( true );
            m_umlObjectMap[item] = cl;
            if( recurse )
            {
                addClassifier( cl, item, true, false, true);
            }

        }
    }
    if(addSub)
    {
        //add derived classifiers
        QListViewItem *derivedFolder = new KListViewItem( classifierItem, i18n("Derived Classifiers") );
        derivedFolder->setExpandable( true );
        UMLClassifierList derived = classifier->findSubClassConcepts();
        for( UMLClassifier *d = derived.first(); d ; d = derived.next() )
        {
            item = new KListViewItem( derivedFolder, d->getName() );
            item->setPixmap(0,m_pixmaps.Subclass);
            item->setExpandable( true );
            m_umlObjectMap[item] = d;
            if( recurse )
            {
                addClassifier( d, item, false, true, true);
            }

        }
    }
}
// we basically want to update the doc and start text of this method
void RubyCodeOperation::updateMethodDeclaration()
{

    CodeDocument * doc = getParentDocument();
    RubyClassifierCodeDocument * rubydoc = dynamic_cast<RubyClassifierCodeDocument*>(doc);
    UMLClassifier *c = rubydoc->getParentClassifier();
    UMLOperation * o = getParentOperation();
    bool isInterface = rubydoc->getParentClassifier()->isInterface();
    QString endLine = getNewLineEndingChars();

    // now, the starting text.
    QString strVis = rubydoc->scopeToRubyDecl(o->getVisibility());
    // no return type for constructors
    QString fixedReturn = RubyCodeGenerator::cppToRubyType(o->getTypeName());
    QString returnType = o->isConstructorOperation() ? QString("") : (fixedReturn + QString(" "));
    QString methodName = o->getName();

    QString RubyClassName = rubydoc->getRubyClassName(c->getName());

    // Skip destructors, and operator methods which
    // can't be defined in ruby
    if (    methodName.startsWith("~")
            || QRegExp("operator\\s*(=|--|\\+\\+|!=)$").exactMatch(methodName) )
    {
        getComment()->setText("");
        return;
    }

    if (RubyClassName == methodName) {
        methodName = "initialize";
    }

    methodName.replace(QRegExp("operator\\s*"), "");
    methodName = methodName.mid(0, 1).lower() + methodName.mid(1);

    QString paramStr = QString("");
    QStringList commentedParams;

    // assemble parameters
    UMLAttributeList list = getParentOperation()->getParmList();
    int nrofParam = list.count();
    int paramNum = 0;
    for(UMLAttribute* parm = list.first(); parm; parm = list.next())
    {
        QString paramName = RubyCodeGenerator::cppToRubyName(parm->getName());
        paramStr += paramName;
        if (! parm->getInitialValue().isEmpty()) {
            paramStr += QString(" = ") + RubyCodeGenerator::cppToRubyType(parm->getInitialValue());
        }
        paramNum++;

        if (paramNum != nrofParam )
            paramStr  += ", ";
    }

    QString startText;
    if (isInterface) {
        // Assume 'isInterface' means a module in Ruby, so
        // generate module methods
        startText = "def "+ RubyClassName + '.' + methodName + '(' + paramStr +')';
    } else {
        startText = "def "+ methodName + '(' + paramStr +')';
    }

    startText += "";
    setEndMethodText("end");

    setStartMethodText(startText);

    // Lastly, for text content generation, we fix the comment on the
    // operation, IF the codeop is autogenerated & currently empty
    QString comment = o->getDoc();

    if (comment.isEmpty()) {
        if (getContentType() == CodeBlock::AutoGenerated) {
            UMLAttributeList parameters = o->getParmList();
            for(UMLAttributeListIt iterator(parameters); iterator.current(); ++iterator) {
                comment += endLine + "* _" + iterator.current()->getName() + "_ ";
                comment += (' ' + iterator.current()->getDoc().replace( QRegExp("[\\n\\r]+[\\t ]*"),
                                                                        endLine + "  " ) );
            }
            // add a returns statement too
            if(!returnType.isEmpty() && !QRegExp("^void\\s*$").exactMatch(returnType))
                comment += endLine + "* _returns_ " + returnType + ' ';
            getComment()->setText(comment);
        }
    } else {
        comment.replace(QRegExp("[\\n\\r]+ *"), endLine);
        comment.replace(QRegExp("[\\n\\r]+\\t*"), endLine);

        comment.replace(" m_", " ");
        comment.replace(QRegExp("\\s[npb](?=[A-Z])"), " ");
        QRegExp re_params("@param (\\w)(\\w*)");
        int pos = re_params.search(comment);
        while (pos != -1) {
            comment.replace( re_params.cap(0),
                            QString("@param _") + re_params.cap(1).lower() + re_params.cap(2) + '_' );
            commentedParams.append(re_params.cap(1).lower() + re_params.cap(2));

            pos += re_params.matchedLength() + 3;
            pos = re_params.search(comment, pos);
        }

        UMLAttributeList parameters = o->getParmList();
        for (UMLAttributeListIt iterator(parameters); iterator.current(); ++iterator) {
            // Only write an individual @param entry if one hasn't been found already
            // in the main doc comment
            if (commentedParams.contains(RubyCodeGenerator::cppToRubyName(iterator.current()->getName())) == 0) {
                comment += (endLine + "@param _" + RubyCodeGenerator::cppToRubyName(iterator.current()->getName()) + '_');
                if (iterator.current()->getDoc().isEmpty()) {
                    comment += (' ' + RubyCodeGenerator::cppToRubyType(iterator.current()->getTypeName()));
                } else {
                    comment += (' ' + iterator.current()->getDoc().replace(QRegExp("[\\n\\r]+[\\t ]*"), endLine + "  "));
                }
            }
        }

        comment.replace("@ref ", "");
        comment.replace("@param", "*");
        comment.replace("@return", "* _returns_");

        // All lines after the first one starting with '*' in the doc comment
        // must be indented correctly. If they aren't a list
        // item starting with '*', then indent the text with
        // two spaces, '  ', to line up with the list item.
        pos = comment.find(endLine + '*');
        if (pos != -1) {
            pos += endLine.length() + 1;
            pos = comment.find(endLine, pos);
        }

        while (pos > 0) {
            pos += endLine.length();
            if (comment[pos] != '*') {
                comment.insert(pos, "  ");
                pos += 2;
            }

            pos = comment.find(endLine, pos);
        }

        QString typeStr = RubyCodeGenerator::cppToRubyType(o->getTypeName());
        if ( !typeStr.isEmpty()
                && !QRegExp("^void\\s*$").exactMatch(typeStr)
                && comment.contains("_returns_") == 0 )
        {
            comment += endLine + "* _returns_ " + typeStr;
        }

        getComment()->setText(comment);
    }

    // In Java, for interfaces..we DONT write out non-public
    // method declarations. And for Ruby modules?
    if (isInterface) {
        UMLOperation * o = getParentOperation();
        if(o->getVisibility() != Uml::Visibility::Public)
            setWriteOutText(false);
    }

}
Beispiel #3
0
void XMLSchemaWriter::writeComplexTypeClassifierDecl (UMLClassifier *c,
        UMLAssociationList associations,
        UMLAssociationList aggregations,
        UMLAssociationList compositions,
        UMLClassifierList superclasses,
        QTextStream &XMLschema)
{

    // Preparations
    //

    // sort attributes by Scope
    UMLAttributeList attribs = findAttributes(c);
    QStringList attribGroups = findAttributeGroups(c);

    // test for relevant associations
    bool hasAssociations = determineIfHasChildNodes(c);
    bool hasSuperclass = superclasses.count()> 0;
    bool hasAttributes = attribs.count() > 0 || attribGroups.count() > 0;

    // START WRITING

    // start body of element
    QString elementTypeName = getElementTypeName(c);

    XMLschema<<getIndent()<<"<"<<makeSchemaTag("complexType")<<" name=\""<<elementTypeName<<"\"";

    if(hasAssociations || hasAttributes || hasSuperclass)
    {

        XMLschema<<">"<<m_endl;

        m_indentLevel++;

        if(hasSuperclass)
        {
            QString superClassName = getElementTypeName(superclasses.first());
            XMLschema<<getIndent()<<"<"<<makeSchemaTag("complexContent")<<">"<<m_endl;

            //PROBLEM: we only treat ONE superclass for inheritence.. bah.
            m_indentLevel++;
            XMLschema<<getIndent()<<"<"<<makeSchemaTag("extension")<<" base=\""<<makePackageTag(superClassName)
            <<"\"";
            if(hasAssociations || hasAttributes )
                XMLschema<<">"<<m_endl;
            else
                XMLschema<<"/>"<<m_endl;

            m_indentLevel++;
        }

        if(hasAssociations)
        {
            // Child Elements (from most associations)
            //
            bool didFirstOne = false;
            didFirstOne = writeAssociationDecls(associations, true, didFirstOne, c->getID(), XMLschema);
            didFirstOne = writeAssociationDecls(aggregations, false, didFirstOne, c->getID(), XMLschema);
            didFirstOne = writeAssociationDecls(compositions, false, didFirstOne, c->getID(), XMLschema);

            if (didFirstOne) {
                m_indentLevel--;
                XMLschema<<getIndent()<<"</"<<makeSchemaTag("sequence")<<">"<<m_endl;
            }
        }

        // ATTRIBUTES
        //
        if(hasAttributes)
        {
            writeAttributeDecls(attribs, XMLschema);
            for(uint i= 0; i < attribGroups.count(); i++)
                XMLschema<<getIndent()<<"<"<<makeSchemaTag("attributeGroup")<<" ref=\""
                <<makePackageTag(attribGroups[i])<<"\"/>"<<m_endl;
        }

        if(hasSuperclass)
        {
            m_indentLevel--;

            if(hasAssociations || hasAttributes )
                XMLschema<<getIndent()<<"</"<<makeSchemaTag("extension")<<">"<<m_endl;

            m_indentLevel--;
            XMLschema<<getIndent()<<"</"<<makeSchemaTag("complexContent")<<">"<<m_endl;
        }

        // close this element decl
        m_indentLevel--;
        XMLschema<<getIndent()<<"</"<<makeSchemaTag("complexType")<<">"<<m_endl;

    } else
        XMLschema<<"/>"<<m_endl; // empty node. just close this element decl

}