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