Generate Getters and Setters functionality into KDevelop
Carlos Nihelton
carlosnsoliveira at gmail.com
Tue Aug 30 00:16:28 UTC 2016
Hi KDevelopers!
I was trying to hack a bit inside KDevelop and decided to implement one
feature into ClangRefactoring class to be able to automatically generate
accessor and mutator member functions for a given member variable
declaration. I think I'm doing right in recognizing the selected
declaration as a member variable and I even got a function declaration
QString by hand manipulation, although I'm quite sure this is not the
right way to do it.
I stuck on how to generate the KDevelop::Declaration for the functions
and how to insert them into code.
Can you guys give me some ideas?
void ClangRefactoring::fillContextMenu(ContextMenuExtension& extension, Context* context){
... [all the existing code]...
/// If the declaration is a member variable, allows for adding getter and
/// setter member functions.
auto memDecl = dynamic_cast<ClassMemberDeclaration*>(declaration);
if(memDecl && !memDecl->isFunctionDeclaration()) {
auto action = new QAction(i18n("Add getter and setter for %1",
declaration->qualifiedIdentifier().toString()),this);
action->setData(QVariant::fromValue(IndexedDeclaration(declaration)));
connect(action, &QAction::triggered, this,
&ClangRefactoring::addGettersAndSetters);
extension.addAction(ContextMenuExtension::RefactorGroup, action);
}
... [all the existing code]...
}
void ClangRefactoring::addGettersAndSetters()
{
QString error;
QMessageBox::information(0, QStringLiteral("Action Triggered"),
QStringLiteral("Add getters and setters"), QMessageBox::Ok);
auto action = qobject_cast<QAction*>(sender());
Q_ASSERT(action);
auto iDecl = action->data().value<IndexedDeclaration>();
if (!iDecl.isValid()) {
iDecl = declarationUnderCursor(false);
}
DUChainReadLocker lock;
auto decl = iDecl.data();
if (!decl) {
error = i18n("No declaration under cursor");
}
const auto headerUrl = decl->url();
auto targetCppUrl = DocumentFinderHelpers::sourceForHeader(headerUrl.str());
if (targetCppUrl.isEmpty() || targetCppUrl == headerUrl.str()) {
// TODO: Create source file if it doesn't exist
error = i18n("No source file available for %1.", headerUrl.str());
}
lock.unlock();
const IndexedString indexedTargetUrl(targetCppUrl);
auto topHeaderContext
= DUChain::self()->waitForUpdate(headerUrl,
KDevelop::TopDUContext::AllDeclarationsAndContexts);
auto targetTopContext
= DUChain::self()->waitForUpdate(indexedTargetUrl,
KDevelop::TopDUContext::AllDeclarationsAndContexts);
lock.lock();
if (!targetTopContext) {
error = i18n("Failed to update DUChain for %1.", targetCppUrl);
}
if (!topHeaderContext || !iDecl.data() || iDecl.data() != decl) {
error = i18n("Declaration lost while updating.");
}
clangDebug() << "Analyzing " << decl->qualifiedIdentifier();
/// Hand manipulation - bad smell.
auto classIdentifier = decl->context()->scopeIdentifier(true).toString();
auto identifier = decl->identifier().toString();
auto type = decl->abstractType()->toString();
identifier.remove(QRegExp(QStringLiteral("^\\w_")));
auto accessorIdentifier =
identifier.replace(0,1,identifier.at(0).toUpper());
accessorIdentifier.prepend(QStringLiteral("get"));
QMessageBox::information(0, QStringLiteral("Action Triggered"),
type+QLatin1Char(' ')+classIdentifier+QStringLiteral("::") +
accessorIdentifier+QStringLiteral("() const;"),
QMessageBox::Ok);
...
}
--
Atenciosamente,
Carlos Nihelton
Engenheiro Eletricista
More information about the KDevelop-devel
mailing list