File indexing completed on 2024-05-12 04:39:08
0001 /* 0002 SPDX-FileCopyrightText: 2009 David Nolden <david.nolden.kdevelop@art-master.de> 0003 SPDX-FileCopyrightText: 2014 Kevin Funk <kfunk@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-only 0006 */ 0007 0008 #include "adaptsignatureaction.h" 0009 #include "codegenhelper.h" 0010 0011 #include "../duchain/duchainutils.h" 0012 #include "../util/clangdebug.h" 0013 0014 #include <language/assistant/renameaction.h> 0015 #include <language/codegen/documentchangeset.h> 0016 #include <language/duchain/duchain.h> 0017 #include <language/duchain/duchainlock.h> 0018 #include <language/duchain/duchainutils.h> 0019 #include <language/duchain/functiondefinition.h> 0020 0021 #include <interfaces/icore.h> 0022 #include <interfaces/iuicontroller.h> 0023 #include <sublime/message.h> 0024 // KF 0025 #include <KLocalizedString> 0026 0027 using namespace KDevelop; 0028 0029 AdaptSignatureAction::AdaptSignatureAction(const DeclarationId& definitionId, 0030 const ReferencedTopDUContext& definitionContext, 0031 const Signature& oldSignature, 0032 const Signature& newSignature, 0033 bool editingDefinition, 0034 const QList<RenameAction*>& renameActions) 0035 : m_otherSideId(definitionId) 0036 , m_otherSideTopContext(definitionContext) 0037 , m_oldSignature(oldSignature) 0038 , m_newSignature(newSignature) 0039 , m_editingDefinition(editingDefinition) 0040 , m_renameActions(renameActions) 0041 { 0042 } 0043 0044 AdaptSignatureAction::~AdaptSignatureAction() 0045 { 0046 qDeleteAll(m_renameActions); 0047 } 0048 0049 QString AdaptSignatureAction::description() const 0050 { 0051 return m_editingDefinition ? i18n("Update declaration signature") : i18n("Update definition signature"); 0052 } 0053 0054 QString AdaptSignatureAction::toolTip() const 0055 { 0056 DUChainReadLocker lock; 0057 auto declaration = m_otherSideId.declaration(m_otherSideTopContext.data()); 0058 if (!declaration) { 0059 return {}; 0060 } 0061 KLocalizedString msg = m_editingDefinition 0062 ? ki18n("Update declaration signature\nfrom: %1\nto: %2") 0063 : ki18n("Update definition signature\nfrom: %1\nto: %2"); 0064 msg = msg.subs(CodegenHelper::makeSignatureString(declaration, m_oldSignature, m_editingDefinition)); 0065 msg = msg.subs(CodegenHelper::makeSignatureString(declaration, m_newSignature, !m_editingDefinition)); 0066 return msg.toString(); 0067 } 0068 0069 void AdaptSignatureAction::execute() 0070 { 0071 ENSURE_CHAIN_NOT_LOCKED 0072 DUChainReadLocker lock; 0073 IndexedString url = m_otherSideTopContext->url(); 0074 lock.unlock(); 0075 m_otherSideTopContext = DUChain::self()->waitForUpdate(url, TopDUContext::AllDeclarationsContextsAndUses); 0076 if (!m_otherSideTopContext) { 0077 clangDebug() << "failed to update" << url.str(); 0078 return; 0079 } 0080 0081 lock.lock(); 0082 0083 Declaration* otherSide = m_otherSideId.declaration(m_otherSideTopContext.data()); 0084 if (!otherSide) { 0085 clangDebug() << "could not find definition"; 0086 return; 0087 } 0088 DUContext* functionContext = DUChainUtils::functionContext(otherSide); 0089 if (!functionContext) { 0090 clangDebug() << "no function context"; 0091 return; 0092 } 0093 if (!functionContext || functionContext->type() != DUContext::Function) { 0094 clangDebug() << "no correct function context"; 0095 return; 0096 } 0097 0098 DocumentChangeSet changes; 0099 KTextEditor::Range parameterRange = ClangIntegration::DUChainUtils::functionSignatureRange(otherSide); 0100 QString newText = CodegenHelper::makeSignatureString(otherSide, m_newSignature, !m_editingDefinition); 0101 if (!m_editingDefinition) { 0102 // append a newline after the method signature in case the method definition follows 0103 newText += QLatin1Char('\n'); 0104 } 0105 0106 DocumentChange changeParameters(functionContext->url(), parameterRange, QString(), newText); 0107 lock.unlock(); 0108 changeParameters.m_ignoreOldText = true; 0109 changes.addChange(changeParameters); 0110 changes.setReplacementPolicy(DocumentChangeSet::WarnOnFailedChange); 0111 DocumentChangeSet::ChangeResult result = changes.applyAllChanges(); 0112 if (!result) { 0113 const QString messageText = i18n("Failed to apply changes: %1", result.m_failureReason); 0114 auto* message = new Sublime::Message(messageText, Sublime::Message::Error); 0115 ICore::self()->uiController()->postMessage(message); 0116 } 0117 emit executed(this); 0118 0119 for (RenameAction* renAct : m_renameActions) { 0120 renAct->execute(); 0121 } 0122 } 0123 0124 #include "moc_adaptsignatureaction.cpp"