File indexing completed on 2024-04-21 15:24:04
0001 /* 0002 SPDX-FileCopyrightText: 2014 Miquel Sabaté <mikisabate@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 0008 #include <QObject> 0009 #include <codegen/refactoring.h> 0010 #include <language/duchain/declaration.h> 0011 #include <language/duchain/use.h> 0012 0013 namespace Php 0014 { 0015 0016 using KDevelop::DocumentChange; 0017 using KDevelop::DocumentChangeSet; 0018 using KDevelop::DUContext; 0019 using KDevelop::TopDUContext; 0020 using KDevelop::IndexedDeclaration; 0021 using KDevelop::Declaration; 0022 using KDevelop::Use; 0023 0024 Refactoring::Refactoring(QObject *parent) 0025 : BasicRefactoring(parent) 0026 { 0027 /* There's nothing to do here. */ 0028 } 0029 0030 DocumentChangeSet::ChangeResult Refactoring::applyChanges( 0031 const QString& oldName, 0032 const QString& newName, 0033 DocumentChangeSet& changes, 0034 DUContext* context, 0035 int usedDeclarationIndex 0036 ) 0037 { 0038 if (usedDeclarationIndex == std::numeric_limits<int>::max()) 0039 return DocumentChangeSet::ChangeResult::successfulResult(); 0040 0041 for (int a = 0; a < context->usesCount(); ++a) { 0042 Use use = context->uses()[a]; 0043 if (use.m_declarationIndex != usedDeclarationIndex) 0044 { 0045 continue; 0046 } 0047 if (use.m_range.isEmpty()) { 0048 continue; 0049 } 0050 0051 if ( shouldRemoveDollar(use.m_range, oldName) ) 0052 { 0053 use.m_range.start.column++; 0054 } 0055 DocumentChangeSet::ChangeResult result = 0056 changes.addChange(DocumentChange(context->url(), context->transformFromLocalRevision(use.m_range), oldName, 0057 newName)); 0058 if (!result) 0059 return result; 0060 } 0061 0062 const auto childContexts = context->childContexts(); 0063 for (DUContext* child : childContexts) { 0064 DocumentChangeSet::ChangeResult result = applyChanges(oldName, newName, changes, child, usedDeclarationIndex); 0065 if (!result) 0066 return result; 0067 } 0068 0069 return DocumentChangeSet::ChangeResult::successfulResult(); 0070 } 0071 0072 DocumentChangeSet::ChangeResult Refactoring::applyChangesToDeclarations(const QString& oldName, 0073 const QString& newName, 0074 DocumentChangeSet& changes, 0075 const QList<IndexedDeclaration>& declarations) 0076 { 0077 KTextEditor::Range range_to_modify; 0078 0079 for (const IndexedDeclaration decl : declarations) { 0080 Declaration *declaration = decl.data(); 0081 if (!declaration) 0082 continue; 0083 TopDUContext *top = declaration->topContext(); 0084 range_to_modify = declaration->rangeInCurrentRevision(); 0085 if ( shouldRemoveDollar(range_to_modify, oldName) ) 0086 { 0087 range_to_modify = KTextEditor::Range( 0088 range_to_modify.start().line(), 0089 range_to_modify.start().column()+1, 0090 range_to_modify.end().line(), 0091 range_to_modify.end().column()); 0092 } 0093 DocumentChangeSet::ChangeResult result = changes.addChange(DocumentChange(top->url(), range_to_modify, oldName, newName)); 0094 if (!result) 0095 return result; 0096 } 0097 return DocumentChangeSet::ChangeResult::successfulResult(); 0098 } 0099 0100 bool Refactoring::shouldRemoveDollar(const KDevelop::RangeInRevision &range, QString name) 0101 { 0102 if ( range.start.line != range.end.line ) 0103 { 0104 return false; 0105 } 0106 return ( range.end.column - range.start.column == name.length() + 1 ); 0107 } 0108 0109 bool Refactoring::shouldRemoveDollar(const KTextEditor::Range &range, QString name) 0110 { 0111 if ( range.start().line() != range.end().line() ) 0112 { 0113 return false; 0114 } 0115 return ( range.columnWidth() == name.length() + 1 ); 0116 } 0117 0118 } // End of namespace Php