cppheadercodeoperation.cpp 6.31 KB
Newer Older
Brian Thomas's avatar
   
Brian Thomas committed
1
2
3
4
5
6
/***************************************************************************
 *   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.                                   *
 *                                                                         *
Andi Fischer's avatar
Andi Fischer committed
7
 *   copyright (C) 2003      Brian Thomas <thomas@mail630.gsfc.nasa.gov>   *
8
 *   copyright (C) 2004-2014                                               *
Ralf Habacker's avatar
Ralf Habacker committed
9
 *   Umbrello UML Modeller Authors <umbrello-devel@kde.org>                *
Brian Thomas's avatar
   
Brian Thomas committed
10
11
12
13
14
 ***************************************************************************/

#include "cppheadercodeoperation.h"

#include "cppcodegenerator.h"
15
#include "cppcodegenerationpolicy.h"
Brian Thomas's avatar
   
Brian Thomas committed
16
17
#include "cppheadercodedocument.h"
#include "cppcodedocumentation.h"
Andi Fischer's avatar
Andi Fischer committed
18
#include "uml.h"
Brian Thomas's avatar
   
Brian Thomas committed
19

20
CPPHeaderCodeOperation::CPPHeaderCodeOperation
21
 (CPPHeaderCodeDocument * doc, UMLOperation *parent, const QString & body, const QString & comment)
22
        : CodeOperation (doc, parent, body, comment)
Brian Thomas's avatar
   
Brian Thomas committed
23
{
24
25
26
27
28
29
30
    // lets not go with the default comment and instead use
    // full-blown cpp documentation object instead
    setComment(new CPPCodeDocumentation(doc));

    // these things never change..
    setOverallIndentationLevel(1);

31
32
33
    setText(QString());
    setStartMethodText(QString());
    setEndMethodText(QString());
Dirk Mueller's avatar
Dirk Mueller committed
34
}
Brian Thomas's avatar
   
Brian Thomas committed
35

36
CPPHeaderCodeOperation::~CPPHeaderCodeOperation()
Andi Fischer's avatar
Andi Fischer committed
37
38
{
}
Brian Thomas's avatar
   
Brian Thomas committed
39

40
41
42
43
// we basically just want to know whether or not to print out
// the body of the operation.
// In C++ if the operations are inline, then we DO print out
// the body text.
44
void CPPHeaderCodeOperation::updateContent()
45
{
46
    CodeGenPolicyExt *pe = UMLApp::app()->policyExt();
47
    CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe);
48
    bool isInlineMethod = policy->getOperationsAreInline();
49

Oliver Kellogg's avatar
Oliver Kellogg committed
50
    if(isInlineMethod)
51
        setText(QString()); // change whatever it is to "";
52
53
}

Brian Thomas's avatar
   
Brian Thomas committed
54
55
56
// we basically want to update the doc and start text of this method
void CPPHeaderCodeOperation::updateMethodDeclaration()
{
57
    ClassifierCodeDocument *ccd = dynamic_cast<ClassifierCodeDocument*>(getParentDocument());
58
    Q_ASSERT(ccd);
59
    bool isInterface = ccd->parentIsInterface();
Oliver Kellogg's avatar
Oliver Kellogg committed
60
    UMLOperation * o = getParentOperation();
Brian Thomas's avatar
   
Brian Thomas committed
61

62
    CodeGenPolicyExt *pe = UMLApp::app()->policyExt();
63
    CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe);
64
    Q_ASSERT(policy);
65
66
    bool isInlineMethod = policy->getOperationsAreInline();
    QString tag = policy->getDocToolTag();
67

Oliver Kellogg's avatar
Oliver Kellogg committed
68
    QString endLine = getNewLineEndingChars();
69

Oliver Kellogg's avatar
Oliver Kellogg committed
70
    // first, the comment on the operation, IF its autogenerated/empty
71
    QString comment = o->doc();
72
    if(comment.isEmpty() && contentType() == CodeBlock::AutoGenerated)
Oliver Kellogg's avatar
Oliver Kellogg committed
73
    {
74
        UMLAttributeList parameters = o->getParmList();
75
        foreach (UMLAttribute* currentAtt, parameters) {
76
            comment += endLine + tag + QLatin1String("param ") + currentAtt->name() + QLatin1Char(' ');
77
            comment += currentAtt->doc();
78
        }
Oliver Kellogg's avatar
Oliver Kellogg committed
79
80
81
82
        getComment()->setText(comment);
    }

    // no return type for constructors
83
    QString methodReturnType = o->getTypeName();
84
    QString methodName = o->name();
85
    QString paramStr;
Oliver Kellogg's avatar
Oliver Kellogg committed
86
87

    // assemble parameters
88
89
    UMLAttributeList list = getParentOperation()->getParmList();
    int nrofParam = list.count();
Oliver Kellogg's avatar
Oliver Kellogg committed
90
    int paramNum = 0;
91
    foreach (UMLAttribute* parm, list) {
Oliver Kellogg's avatar
Oliver Kellogg committed
92
        QString rType = parm->getTypeName();
93
        QString paramName = parm->name();
Oliver Kellogg's avatar
Oliver Kellogg committed
94
        QString initialValue = parm->getInitialValue();
95
        paramStr += rType + QLatin1Char(' ') + paramName;
Oliver Kellogg's avatar
Oliver Kellogg committed
96
        if(!initialValue.isEmpty())
97
            paramStr += QLatin1Char('=') + initialValue;
Oliver Kellogg's avatar
Oliver Kellogg committed
98
99
100

        paramNum++;

101
        if (paramNum != nrofParam)
102
            paramStr  += QLatin1String(", ");
Oliver Kellogg's avatar
Oliver Kellogg committed
103
104
    }

105
    // if an operation isn't a constructor or a destructor and it has no return type
106
    if (o->isLifeOperation())         // constructor/destructor has no type
107
        methodReturnType = QString();
108
    else if (methodReturnType.isEmpty())  // this operation should be 'void'
109
        methodReturnType = QString(QLatin1String("void"));
110

Oliver Kellogg's avatar
Oliver Kellogg committed
111
    // set start/end method text
112
    QString prototype = methodReturnType + QLatin1Char(' ') + methodName + QLatin1String(" (") + paramStr + QLatin1Char(')');
Oliver Kellogg's avatar
Oliver Kellogg committed
113

114
115
    QString startText;
    QString endText;
Oliver Kellogg's avatar
Oliver Kellogg committed
116

117
    applyStereotypes (prototype, o, isInlineMethod, isInterface, startText, endText);
Oliver Kellogg's avatar
Oliver Kellogg committed
118

119
    setStartMethodText(prototype + startText);
Oliver Kellogg's avatar
Oliver Kellogg committed
120
    setEndMethodText(endText);
Brian Thomas's avatar
   
Brian Thomas committed
121
122
}

Andi Fischer's avatar
Andi Fischer committed
123
124
int CPPHeaderCodeOperation::lastEditableLine()
{
125
    ClassifierCodeDocument * doc = dynamic_cast<ClassifierCodeDocument*>(getParentDocument());
Oliver Kellogg's avatar
Oliver Kellogg committed
126
    UMLOperation * o = getParentOperation();
127
    if(doc->parentIsInterface() || o->isAbstract())
Oliver Kellogg's avatar
Oliver Kellogg committed
128
129
130
        return -1; // very last line is NOT editable as its a one-line declaration w/ no body in
    // an interface.
    return 0;
131
132
}

133
134
135
136
137
138
void CPPHeaderCodeOperation::applyStereotypes (QString& prototype, UMLOperation * pOp,
                                               bool inlinePolicy, bool interface,
                                               QString& start, QString& end)
{
    // if the class is an interface, all methods will be declared as pure
    // virtual functions
139
140
    start = (inlinePolicy ? QLatin1String(" {") : QLatin1String(";"));
    end = (inlinePolicy ? QLatin1String("}") : QString());
141
    if (pOp->getConst())
142
        prototype += QLatin1String(" const");
143
    if (interface || pOp->isAbstract()) {
144
       // constructor can't be virtual or abstract
145
       if (!pOp->isLifeOperation()) {
146
           prototype = QLatin1String("virtual ") + prototype + QLatin1String(" = 0");
147
           if (inlinePolicy) {
148
               start = QLatin1Char(';');
149
               end = QString();
150
151
152
           }
       }
    } // constructors could not be declared as static
153
    else if (pOp->isStatic() && !pOp->isLifeOperation()) {
154
       prototype = QLatin1String("static ") + prototype;
155
156
    }
    // apply the stereotypes
157
    if (!pOp->stereotype().isEmpty()) {
158
        if ((pOp->stereotype() == QLatin1String("friend")) || (pOp->stereotype(false) == QLatin1String("virtual"))) {
159
            if (!pOp->isLifeOperation() && !(interface || pOp->isAbstract()) && !pOp->isStatic())
160
                prototype = pOp->stereotype() + QLatin1Char(' ') + prototype;
161
162
163
164
        }
    }
}