C++: Automatic Doxygen comment blocks generation

This improves our completion support for documentation
comments. It's now possible to have a Doxygen block
generated when hitting enter after a /** or /*! comment
start. A couple other related options are also available.

Task-number: QTCREATORBUG-2752
Task-number: QTCREATORBUG-3165

Change-Id: I1c81c0b4b370eb1d409ef72a9c7f22c357f202f4
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@nokia.com>
Reviewed-by: Christian Kamm <christian.d.kamm@nokia.com>
This commit is contained in:
Leandro Melo
2011-12-07 15:05:02 +01:00
parent 24b4c12737
commit beede7d7cf
13 changed files with 723 additions and 15 deletions

View File

@@ -0,0 +1,46 @@
#include "commentssettings.h"
#include <QtCore/QSettings>
using namespace CppTools;
namespace {
const char kDocumentationCommentsGroup[] = "DocumentationComments";
const char kEnableDoxygenBlocks[] = "EnableDoxygenBlocks";
const char kGenerateBrief[] = "GenerateBrief";
const char kAddLeadingAsterisks[] = "AddLeadingAsterisks";
}
CommentsSettings::CommentsSettings()
: m_enableDoxygen(true)
, m_generateBrief(true)
, m_leadingAsterisks(true)
{}
void CommentsSettings::toSettings(const QString &category, QSettings *s) const
{
s->beginGroup(category + QLatin1String(kDocumentationCommentsGroup));
s->setValue(QLatin1String(kEnableDoxygenBlocks), m_enableDoxygen);
s->setValue(QLatin1String(kGenerateBrief), m_generateBrief);
s->setValue(QLatin1String(kAddLeadingAsterisks), m_leadingAsterisks);
s->endGroup();
}
void CommentsSettings::fromSettings(const QString &category, QSettings *s)
{
s->beginGroup(category + QLatin1String(kDocumentationCommentsGroup));
m_enableDoxygen = s->value(QLatin1String(kEnableDoxygenBlocks), true).toBool();
m_generateBrief = m_enableDoxygen
&& s->value(QLatin1String(kGenerateBrief), true).toBool();
m_leadingAsterisks = s->value(QLatin1String(kAddLeadingAsterisks), true).toBool();
s->endGroup();
}
bool CommentsSettings::equals(const CommentsSettings &other) const
{
return m_enableDoxygen == other.m_enableDoxygen
&& m_generateBrief == other.m_generateBrief
&& m_leadingAsterisks == other.m_leadingAsterisks;
}

View File

@@ -0,0 +1,35 @@
#ifndef COMMENTSSETTINGS_H
#define COMMENTSSETTINGS_H
#include "cpptools_global.h"
QT_BEGIN_NAMESPACE
class QSettings;
QT_END_NAMESPACE
namespace CppTools {
class CPPTOOLS_EXPORT CommentsSettings
{
public:
CommentsSettings();
void toSettings(const QString &category, QSettings *s) const;
void fromSettings(const QString &category, QSettings *s);
bool equals(const CommentsSettings &other) const;
bool m_enableDoxygen;
bool m_generateBrief;
bool m_leadingAsterisks;
};
inline bool operator==(const CommentsSettings &a, const CommentsSettings &b)
{ return a.equals(b); }
inline bool operator!=(const CommentsSettings &a, const CommentsSettings &b)
{ return !(a == b); }
} // namespace CppTools
#endif // COMMENTSSETTINGS_H

View File

@@ -32,6 +32,7 @@
#include "completionsettingspage.h"
#include "ui_completionsettingspage.h"
#include "cpptoolsconstants.h"
#include <coreplugin/icore.h>
#include <extensionsystem/pluginmanager.h>
@@ -40,11 +41,16 @@
#include <QtCore/QTextStream>
#include <QtCore/QCoreApplication>
using namespace CppTools;
using namespace CppTools::Internal;
using namespace CppTools::Constants;
CompletionSettingsPage::CompletionSettingsPage()
: m_page(0)
CompletionSettingsPage::CompletionSettingsPage(QObject *parent)
: TextEditor::TextEditorOptionsPage(parent)
, m_page(0)
{
if (QSettings *s = Core::ICore::instance()->settings())
m_commentsSettings.fromSettings(QLatin1String(CPPTOOLS_SETTINGSGROUP), s);
}
CompletionSettingsPage::~CompletionSettingsPage()
@@ -103,6 +109,9 @@ QWidget *CompletionSettingsPage::createPage(QWidget *parent)
m_page->surroundSelectedText->setChecked(settings.m_surroundingAutoBrackets);
m_page->partiallyComplete->setChecked(settings.m_partiallyComplete);
m_page->spaceAfterFunctionName->setChecked(settings.m_spaceAfterFunctionName);
m_page->enableDoxygenCheckBox->setChecked(m_commentsSettings.m_enableDoxygen);
m_page->generateBriefCheckBox->setChecked(m_commentsSettings.m_generateBrief);
m_page->leadingAsterisksCheckBox->setChecked(m_commentsSettings.m_leadingAsterisks);
if (m_searchKeywords.isEmpty()) {
QTextStream(&m_searchKeywords) << m_page->caseSensitivityLabel->text()
@@ -110,10 +119,15 @@ QWidget *CompletionSettingsPage::createPage(QWidget *parent)
<< ' ' << m_page->surroundSelectedText->text()
<< ' ' << m_page->completionTriggerLabel->text()
<< ' ' << m_page->partiallyComplete->text()
<< ' ' << m_page->spaceAfterFunctionName->text();
<< ' ' << m_page->spaceAfterFunctionName->text()
<< ' ' << m_page->enableDoxygenCheckBox->text()
<< ' ' << m_page->generateBriefCheckBox->text()
<< ' ' << m_page->leadingAsterisksCheckBox->text();
m_searchKeywords.remove(QLatin1Char('&'));
}
m_page->generateBriefCheckBox->setEnabled(m_page->enableDoxygenCheckBox->isChecked());
return w;
}
@@ -130,6 +144,17 @@ void CompletionSettingsPage::apply()
settings.m_spaceAfterFunctionName = m_page->spaceAfterFunctionName->isChecked();
TextEditor::TextEditorSettings::instance()->setCompletionSettings(settings);
if (!requireCommentsSettingsUpdate())
return;
m_commentsSettings.m_enableDoxygen = m_page->enableDoxygenCheckBox->isChecked();
m_commentsSettings.m_generateBrief = m_page->generateBriefCheckBox->isChecked();
m_commentsSettings.m_leadingAsterisks = m_page->leadingAsterisksCheckBox->isChecked();
if (QSettings *s = Core::ICore::instance()->settings())
m_commentsSettings.toSettings(QLatin1String(CPPTOOLS_SETTINGSGROUP), s);
emit commentsSettingsChanged(m_commentsSettings);
}
bool CompletionSettingsPage::matches(const QString &s) const
@@ -168,3 +193,15 @@ void CompletionSettingsPage::finish()
delete m_page;
m_page = 0;
}
const CommentsSettings &CompletionSettingsPage::commentsSettings() const
{
return m_commentsSettings;
}
bool CompletionSettingsPage::requireCommentsSettingsUpdate() const
{
return m_commentsSettings.m_enableDoxygen != m_page->enableDoxygenCheckBox->isChecked()
|| m_commentsSettings.m_generateBrief != m_page->generateBriefCheckBox->isChecked()
|| m_commentsSettings.m_leadingAsterisks != m_page->leadingAsterisksCheckBox->isChecked();
}

View File

@@ -33,13 +33,17 @@
#ifndef COMPLETIONSETTINGSPAGE_H
#define COMPLETIONSETTINGSPAGE_H
#include "commentssettings.h"
#include <texteditor/completionsettings.h>
#include <texteditor/texteditoroptionspage.h>
namespace CppTools {
namespace Internal {
namespace Ui { class CompletionSettingsPage; }
namespace Ui {
class CompletionSettingsPage;
}
// TODO: Move this class to the text editor plugin
@@ -48,7 +52,7 @@ class CompletionSettingsPage : public TextEditor::TextEditorOptionsPage
Q_OBJECT
public:
CompletionSettingsPage();
CompletionSettingsPage(QObject *parent);
~CompletionSettingsPage();
QString id() const;
@@ -59,12 +63,20 @@ public:
void finish();
virtual bool matches(const QString &) const;
const CommentsSettings &commentsSettings() const;
signals:
void commentsSettingsChanged(const CppTools::CommentsSettings &settings);
private:
TextEditor::CaseSensitivity caseSensitivity() const;
TextEditor::CompletionTrigger completionTrigger() const;
bool requireCommentsSettingsUpdate() const;
Ui::CompletionSettingsPage *m_page;
QString m_searchKeywords;
CommentsSettings m_commentsSettings;
};
} // namespace Internal

View File

@@ -6,11 +6,11 @@
<rect>
<x>0</x>
<y>0</y>
<width>393</width>
<height>241</height>
<width>484</width>
<height>376</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
@@ -196,6 +196,65 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="docCommentsGroup">
<property name="title">
<string>Documentation Comments</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="enableDoxygenCheckBox">
<property name="toolTip">
<string>Automatically create a Doxygen comment upon pressing enter after a /** or /*!</string>
</property>
<property name="text">
<string>Enable Doxygen blocks</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>30</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="generateBriefCheckBox">
<property name="toolTip">
<string>Generate a &lt;i&gt;brief&lt;/i&gt; command with an initial description for the corresponding declaration</string>
</property>
<property name="text">
<string>Generate brief description</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="leadingAsterisksCheckBox">
<property name="toolTip">
<string>Add leading asterisks when continuing comments on new lines</string>
</property>
<property name="text">
<string>Add leading asterisks</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
@@ -224,8 +283,8 @@
<y>131</y>
</hint>
<hint type="destinationlabel">
<x>265</x>
<y>182</y>
<x>333</x>
<y>206</y>
</hint>
</hints>
</connection>
@@ -245,5 +304,21 @@
</hint>
</hints>
</connection>
<connection>
<sender>enableDoxygenCheckBox</sender>
<signal>toggled(bool)</signal>
<receiver>generateBriefCheckBox</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>153</x>
<y>272</y>
</hint>
<hint type="destinationlabel">
<x>204</x>
<y>293</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -35,7 +35,9 @@ HEADERS += completionsettingspage.h \
cppcodestylesettings.h \
cppcodestylepreferencesfactory.h \
cppcodestylepreferences.h \
cpptoolsreuse.h
cpptoolsreuse.h \
doxygengenerator.h \
commentssettings.h
SOURCES += completionsettingspage.cpp \
cppclassesfilter.cpp \
@@ -62,7 +64,9 @@ SOURCES += completionsettingspage.cpp \
cppcodestylesettings.cpp \
cppcodestylepreferencesfactory.cpp \
cppcodestylepreferences.cpp \
cpptoolsreuse.cpp
cpptoolsreuse.cpp \
doxygengenerator.cpp \
commentssettings.cpp
FORMS += completionsettingspage.ui \
cppfilesettingspage.ui \

View File

@@ -122,7 +122,6 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
addAutoReleasedObject(new CppClassesFilter(m_modelManager));
addAutoReleasedObject(new CppFunctionsFilter(m_modelManager));
addAutoReleasedObject(new CppCurrentDocumentFilter(m_modelManager, core->editorManager()));
addAutoReleasedObject(new CompletionSettingsPage);
addAutoReleasedObject(new CppFileSettingsPage(m_fileSettings));
addAutoReleasedObject(new SymbolsFindFilter(m_modelManager));
addAutoReleasedObject(new CppCodeStyleSettingsPage);

View File

@@ -34,11 +34,14 @@
#include "cpptoolsconstants.h"
#include "cppcodestylepreferences.h"
#include "cppcodestylepreferencesfactory.h"
#include "commentssettings.h"
#include "completionsettingspage.h"
#include <texteditor/texteditorsettings.h>
#include <texteditor/texteditorsettings.h>
#include <texteditor/tabsettings.h>
#include <texteditor/codestylepool.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/settingsutils.h>
#include <utils/qtcassert.h>
@@ -48,6 +51,7 @@
static const char *idKey = "CppGlobal";
using namespace CppTools;
using namespace CppTools::Internal;
using TextEditor::TabSettings;
namespace CppTools {
@@ -56,7 +60,13 @@ namespace Internal {
class CppToolsSettingsPrivate
{
public:
CppToolsSettingsPrivate()
: m_globalCodeStyle(0)
, m_completionSettingsPage(0)
{}
CppCodeStylePreferences *m_globalCodeStyle;
CompletionSettingsPage *m_completionSettingsPage;
};
} // namespace Internal
@@ -70,8 +80,17 @@ CppToolsSettings::CppToolsSettings(QObject *parent)
{
QTC_ASSERT(!m_instance, return);
m_instance = this;
qRegisterMetaType<CppTools::CppCodeStyleSettings>("CppTools::CppCodeStyleSettings");
d->m_completionSettingsPage = new CompletionSettingsPage(this);
ExtensionSystem::PluginManager::instance()->addObject(d->m_completionSettingsPage);
connect(d->m_completionSettingsPage,
SIGNAL(commentsSettingsChanged(CppTools::CommentsSettings)),
this,
SIGNAL(commentsSettingsChanged(CppTools::CommentsSettings)));
TextEditor::TextEditorSettings *textEditorSettings = TextEditor::TextEditorSettings::instance();
// code style factory
@@ -224,6 +243,8 @@ CppToolsSettings::CppToolsSettings(QObject *parent)
CppToolsSettings::~CppToolsSettings()
{
ExtensionSystem::PluginManager::instance()->removeObject(d->m_completionSettingsPage);
delete d;
m_instance = 0;
@@ -239,3 +260,7 @@ CppCodeStylePreferences *CppToolsSettings::cppCodeStyle() const
return d->m_globalCodeStyle;
}
const CommentsSettings &CppToolsSettings::commentsSettings() const
{
return d->m_completionSettingsPage->commentsSettings();
}

View File

@@ -40,7 +40,7 @@
namespace CppTools
{
class CppCodeStylePreferences;
class CommentsSettings;
namespace Internal
{
@@ -61,6 +61,10 @@ public:
static CppToolsSettings *instance();
CppCodeStylePreferences *cppCodeStyle() const;
const CommentsSettings &commentsSettings() const;
signals:
void commentsSettingsChanged(const CppTools::CommentsSettings &settings);
private:
Internal::CppToolsSettingsPrivate *d;

View File

@@ -0,0 +1,289 @@
#include "doxygengenerator.h"
#include <cplusplus/SimpleLexer.h>
#include <cplusplus/BackwardsScanner.h>
#include <cplusplus/Token.h>
#include <cplusplus/TranslationUnit.h>
#include <cplusplus/AST.h>
#include <cplusplus/Symbols.h>
#include <cplusplus/CppDocument.h>
#include <cplusplus/Scope.h>
#include <cplusplus/LookupContext.h>
#include <QtCore/QStringBuilder>
#include <QtGui/QTextDocument>
#include <QDebug>
using namespace CppTools;
using namespace CPlusPlus;
DoxygenGenerator::DoxygenGenerator()
: m_addLeadingAsterisks(true)
, m_generateBrief(true)
, m_startComment(true)
, m_style(QtStyle)
, m_commentOffset(0)
{}
void DoxygenGenerator::setStyle(DocumentationStyle style)
{
m_style = style;
}
void DoxygenGenerator::setStartComment(bool start)
{
m_startComment = start;
}
void DoxygenGenerator::setGenerateBrief(bool get)
{
m_generateBrief = get;
}
void DoxygenGenerator::setAddLeadingAsterisks(bool add)
{
m_addLeadingAsterisks = add;
}
QString DoxygenGenerator::generate(QTextCursor cursor)
{
const QChar &c = cursor.document()->characterAt(cursor.position());
if (!c.isLetter() && c != QLatin1Char('_'))
return QString();
// Try to find what would be the declaration we are interested in.
SimpleLexer lexer;
QTextBlock block = cursor.block();
while (block.isValid()) {
const QString &text = block.text();
const QList<Token> &tks = lexer(text);
foreach (const Token &tk, tks) {
if (tk.is(T_SEMICOLON) || tk.is(T_LBRACE)) {
// No need to continue beyond this, we might already have something meaningful.
cursor.setPosition(block.position() + tk.end(), QTextCursor::KeepAnchor);
break;
}
}
if (cursor.hasSelection())
break;
block = block.next();
}
if (!cursor.hasSelection())
return QString();
QString declCandidate = cursor.selectedText();
declCandidate.replace(QChar::ParagraphSeparator, QLatin1Char('\n'));
// Let's append a closing brace in the case we got content like 'class MyType {'
if (declCandidate.endsWith(QLatin1Char('{')))
declCandidate.append(QLatin1Char('}'));
Document::Ptr doc = Document::create(QLatin1String("<doxygen>"));
doc->setSource(declCandidate.toUtf8());
doc->parse(Document::ParseDeclaration);
doc->check(Document::FastCheck);
if (!doc->translationUnit()
|| !doc->translationUnit()->ast()
|| !doc->translationUnit()->ast()->asDeclaration()) {
return QString();
}
return generate(cursor, doc->translationUnit()->ast()->asDeclaration());
}
QString DoxygenGenerator::generate(QTextCursor cursor, CPlusPlus::DeclarationAST *decl)
{
SpecifierAST *spec = 0;
DeclaratorAST *decltr = 0;
if (SimpleDeclarationAST *simpleDecl = decl->asSimpleDeclaration()) {
if (simpleDecl->declarator_list
&& simpleDecl->declarator_list->value) {
decltr = simpleDecl->declarator_list->value;
} else if (simpleDecl->decl_specifier_list
&& simpleDecl->decl_specifier_list->value) {
spec = simpleDecl->decl_specifier_list->value;
}
} else if (FunctionDefinitionAST * defDecl = decl->asFunctionDefinition()) {
decltr = defDecl->declarator;
}
assignCommentOffset(cursor);
QString comment;
if (m_startComment)
writeStart(&comment);
writeNewLine(&comment);
writeContinuation(&comment);
if (decltr
&& decltr->core_declarator
&& decltr->core_declarator->asDeclaratorId()
&& decltr->core_declarator->asDeclaratorId()->name) {
CoreDeclaratorAST *coreDecl = decltr->core_declarator;
if (m_generateBrief)
writeBrief(&comment, m_printer.prettyName(coreDecl->asDeclaratorId()->name->name));
else
writeNewLine(&comment);
if (decltr->postfix_declarator_list
&& decltr->postfix_declarator_list->value
&& decltr->postfix_declarator_list->value->asFunctionDeclarator()) {
FunctionDeclaratorAST *funcDecltr =
decltr->postfix_declarator_list->value->asFunctionDeclarator();
if (funcDecltr->parameter_declaration_clause
&& funcDecltr->parameter_declaration_clause->parameter_declaration_list) {
for (ParameterDeclarationListAST *it =
funcDecltr->parameter_declaration_clause->parameter_declaration_list;
it;
it = it->next) {
ParameterDeclarationAST *paramDecl = it->value;
if (paramDecl->declarator
&& paramDecl->declarator->core_declarator
&& paramDecl->declarator->core_declarator->asDeclaratorId()
&& paramDecl->declarator->core_declarator->asDeclaratorId()->name) {
DeclaratorIdAST *paramId =
paramDecl->declarator->core_declarator->asDeclaratorId();
writeContinuation(&comment);
writeCommand(&comment,
ParamCommand,
m_printer.prettyName(paramId->name->name));
}
}
}
if (funcDecltr->symbol
&& funcDecltr->symbol->returnType().type()
&& !funcDecltr->symbol->returnType()->isVoidType()
&& !funcDecltr->symbol->returnType()->isUndefinedType()) {
writeContinuation(&comment);
writeCommand(&comment, ReturnCommand);
}
}
} else if (spec && m_generateBrief) {
bool briefWritten = false;
if (ClassSpecifierAST *classSpec = spec->asClassSpecifier()) {
if (classSpec->name) {
QString aggregate;
if (classSpec->symbol->isClass())
aggregate = QLatin1String("class");
else if (classSpec->symbol->isStruct())
aggregate = QLatin1String("struct");
else
aggregate = QLatin1String("union");
writeBrief(&comment,
m_printer.prettyName(classSpec->name->name),
QLatin1String("The"),
aggregate);
briefWritten = true;
}
} else if (EnumSpecifierAST *enumSpec = spec->asEnumSpecifier()) {
if (enumSpec->name) {
writeBrief(&comment,
m_printer.prettyName(enumSpec->name->name),
QLatin1String("The"),
QLatin1String("enum"));
briefWritten = true;
}
}
if (!briefWritten)
writeNewLine(&comment);
} else {
writeNewLine(&comment);
}
writeEnd(&comment);
return comment;
}
QChar DoxygenGenerator::startMark() const
{
if (m_style == QtStyle)
return QLatin1Char('!');
return QLatin1Char('*');
}
QChar DoxygenGenerator::styleMark() const
{
if (m_style == QtStyle)
return QLatin1Char('\\');
return QLatin1Char('@');
}
QString DoxygenGenerator::commandSpelling(Command command)
{
if (command == ParamCommand)
return QLatin1String("param ");
if (command == ReturnCommand)
return QLatin1String("return ");
Q_ASSERT(command == BriefCommand);
return QLatin1String("brief ");
}
void DoxygenGenerator::writeStart(QString *comment) const
{
comment->append(offsetString() % QLatin1String("/*") % startMark());
}
void DoxygenGenerator::writeEnd(QString *comment) const
{
comment->append(offsetString() % QLatin1String(" */"));
}
void DoxygenGenerator::writeContinuation(QString *comment) const
{
if (m_addLeadingAsterisks)
comment->append(offsetString() % QLatin1String(" *"));
else
comment->append(offsetString() % QLatin1String(" "));
}
void DoxygenGenerator::writeNewLine(QString *comment) const
{
comment->append(QLatin1Char('\n'));
}
void DoxygenGenerator::writeCommand(QString *comment,
Command command,
const QString &commandContent) const
{
comment->append(QLatin1Char(' ')
% styleMark()
% commandSpelling(command)
% commandContent
% QLatin1Char('\n'));
}
void DoxygenGenerator::writeBrief(QString *comment,
const QString &brief,
const QString &prefix,
const QString &suffix)
{
QString content = prefix % QLatin1Char(' ') % brief % QLatin1Char(' ') % suffix;
writeCommand(comment, BriefCommand, content.trimmed());
}
void DoxygenGenerator::assignCommentOffset(QTextCursor cursor)
{
if (cursor.hasSelection()) {
if (cursor.anchor() < cursor.position())
cursor.setPosition(cursor.anchor());
}
m_commentOffset = cursor.positionInBlock();
}
QString DoxygenGenerator::offsetString() const
{
// Note: Currently we don't indent comments, but simply preserve them in the original
// relative positions. What we do here is just to make sure that such positions are correct,
// although they might still be wrong from an indentation point of view (for instance,
// using spaces instead of tabs). Therefore, the content generated should still have
// the indentation strings fixed.
return QString(m_commentOffset, QLatin1Char(' '));
}

View File

@@ -0,0 +1,71 @@
#ifndef DOXYGEGENERATOR_H
#define DOXYGEGENERATOR_H
#include "cpptools_global.h"
#include <cplusplus/Overview.h>
#include <QtCore/QLatin1String>
#include <QtGui/QTextCursor>
namespace CPlusPlus {
class DeclarationAST;
}
namespace CppTools {
class CPPTOOLS_EXPORT DoxygenGenerator
{
public:
DoxygenGenerator();
enum DocumentationStyle {
JavaStyle,
QtStyle
};
void setStyle(DocumentationStyle style);
void setStartComment(bool start);
void setGenerateBrief(bool gen);
void setAddLeadingAsterisks(bool add);
QString generate(QTextCursor cursor);
QString generate(QTextCursor cursor, CPlusPlus::DeclarationAST *decl);
private:
QChar startMark() const;
QChar styleMark() const;
enum Command {
BriefCommand,
ParamCommand,
ReturnCommand
};
static QString commandSpelling(Command command);
void writeStart(QString *comment) const;
void writeEnd(QString *comment) const;
void writeContinuation(QString *comment) const;
void writeNewLine(QString *comment) const;
void writeCommand(QString *comment,
Command command,
const QString &commandContent = QString()) const;
void writeBrief(QString *comment,
const QString &brief,
const QString &prefix = QString(),
const QString &suffix = QString());
void assignCommentOffset(QTextCursor cursor);
QString offsetString() const;
bool m_addLeadingAsterisks;
bool m_generateBrief;
bool m_startComment;
DocumentationStyle m_style;
CPlusPlus::Overview m_printer;
int m_commentOffset;
};
} // CppTools
#endif // DOXYGEGENERATOR_H