forked from qt-creator/qt-creator
Clang: Add clang refactoring
Change-Id: I2e3f36f810276da3f8dc7dcc587b06f8edb586d3 GPush-Base: d02f51b48fc752fddcdef6dcb32b3f7f6c0195a3 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -38,6 +38,8 @@
|
||||
#include "cppquickfixassistant.h"
|
||||
#include "cppuseselectionsupdater.h"
|
||||
|
||||
#include <clangbackendipc/sourcelocationscontainer.h>
|
||||
|
||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
@@ -55,6 +57,7 @@
|
||||
#include <cpptools/cpptoolsreuse.h>
|
||||
#include <cpptools/cppworkingcopy.h>
|
||||
#include <cpptools/symbolfinder.h>
|
||||
#include <cpptools/refactoringengineinterface.h>
|
||||
|
||||
#include <texteditor/behaviorsettings.h>
|
||||
#include <texteditor/completionsettings.h>
|
||||
@@ -68,11 +71,14 @@
|
||||
#include <texteditor/fontsettings.h>
|
||||
#include <texteditor/refactoroverlay.h>
|
||||
|
||||
#include <projectexplorer/projecttree.h>
|
||||
|
||||
#include <cplusplus/ASTPath.h>
|
||||
#include <cplusplus/FastPreprocessor.h>
|
||||
#include <cplusplus/MatchingText.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QAction>
|
||||
#include <QElapsedTimer>
|
||||
#include <QFutureWatcher>
|
||||
@@ -377,8 +383,17 @@ bool CppEditorWidget::selectBlockDown()
|
||||
}
|
||||
|
||||
void CppEditorWidget::renameSymbolUnderCursor()
|
||||
{
|
||||
if (refactoringEngine())
|
||||
renameSymbolUnderCursorClang();
|
||||
else
|
||||
renameSymbolUnderCursorBuiltin();
|
||||
}
|
||||
|
||||
void CppEditorWidget::renameSymbolUnderCursorBuiltin()
|
||||
{
|
||||
d->m_useSelectionsUpdater.abortSchedule();
|
||||
|
||||
updateSemanticInfo(d->m_cppEditorDocument->recalculateSemanticInfo(),
|
||||
/*updateUseSelectionSynchronously=*/ true);
|
||||
|
||||
@@ -386,6 +401,129 @@ void CppEditorWidget::renameSymbolUnderCursor()
|
||||
renameUsages(); // Rename non-local symbol or macro
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
QList<ProjectPart::Ptr> fetchProjectParts(CppTools::CppModelManager *modelManager,
|
||||
const Utils::FileName &filePath)
|
||||
{
|
||||
QList<ProjectPart::Ptr> projectParts = modelManager->projectPart(filePath);
|
||||
|
||||
if (projectParts.isEmpty())
|
||||
projectParts = modelManager->projectPartFromDependencies(filePath);
|
||||
else if (projectParts.isEmpty())
|
||||
projectParts.append(modelManager->fallbackProjectPart());
|
||||
|
||||
return projectParts;
|
||||
}
|
||||
|
||||
ProjectPart *findProjectPartForCurrentProject(const QList<ProjectPart::Ptr> &projectParts,
|
||||
ProjectExplorer::Project *currentProject)
|
||||
{
|
||||
auto found = std::find_if(projectParts.cbegin(),
|
||||
projectParts.cend(),
|
||||
[&] (const CppTools::ProjectPart::Ptr &projectPart) {
|
||||
return projectPart->project == currentProject;
|
||||
});
|
||||
|
||||
if (found != projectParts.cend())
|
||||
return (*found).data();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ProjectPart *CppEditorWidget::projectPart() const
|
||||
{
|
||||
auto projectParts = fetchProjectParts(d->m_modelManager, textDocument()->filePath());
|
||||
|
||||
return findProjectPartForCurrentProject(projectParts,
|
||||
ProjectExplorer::ProjectTree::currentProject());
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
using ClangBackEnd::V2::SourceLocationContainer;
|
||||
using TextEditor::Convenience::selectAt;
|
||||
|
||||
QTextCharFormat occurrencesTextCharFormat()
|
||||
{
|
||||
using TextEditor::TextEditorSettings;
|
||||
|
||||
return TextEditorSettings::fontSettings().toTextCharFormat(TextEditor::C_OCCURRENCES);
|
||||
}
|
||||
|
||||
QList<QTextEdit::ExtraSelection>
|
||||
sourceLocationsToExtraSelections(const std::vector<SourceLocationContainer> &sourceLocations,
|
||||
uint selectionLength,
|
||||
CppEditorWidget *cppEditorWidget)
|
||||
{
|
||||
const auto textCharFormat = occurrencesTextCharFormat();
|
||||
|
||||
QList<QTextEdit::ExtraSelection> selections;
|
||||
selections.reserve(sourceLocations.size());
|
||||
|
||||
auto sourceLocationToExtraSelection = [&] (const SourceLocationContainer &sourceLocation) {
|
||||
QTextEdit::ExtraSelection selection;
|
||||
|
||||
selection.cursor = selectAt(cppEditorWidget->textCursor(),
|
||||
sourceLocation.line(),
|
||||
sourceLocation.column(),
|
||||
selectionLength);
|
||||
selection.format = textCharFormat;
|
||||
|
||||
return selection;
|
||||
};
|
||||
|
||||
|
||||
std::transform(sourceLocations.begin(),
|
||||
sourceLocations.end(),
|
||||
std::back_inserter(selections),
|
||||
sourceLocationToExtraSelection);
|
||||
|
||||
return selections;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void CppEditorWidget::renameSymbolUnderCursorClang()
|
||||
{
|
||||
using ClangBackEnd::SourceLocationsContainer;
|
||||
|
||||
if (refactoringEngine()->isUsable()) {
|
||||
d->m_useSelectionsUpdater.abortSchedule();
|
||||
|
||||
QPointer<CppEditorWidget> cppEditorWidget = this;
|
||||
|
||||
auto renameSymbols = [=] (const QString &symbolName,
|
||||
const SourceLocationsContainer &sourceLocations,
|
||||
int revision) {
|
||||
if (cppEditorWidget) {
|
||||
viewport()->setCursor(Qt::IBeamCursor);
|
||||
|
||||
if (revision == document()->revision()) {
|
||||
auto selections = sourceLocationsToExtraSelections(sourceLocations.sourceLocationContainers(),
|
||||
symbolName.size(),
|
||||
cppEditorWidget);
|
||||
setExtraSelections(TextEditor::TextEditorWidget::CodeSemanticsSelection,
|
||||
selections);
|
||||
d->m_localRenaming.updateSelectionsForVariableUnderCursor(selections);
|
||||
if (!d->m_localRenaming.start())
|
||||
renameUsages();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
refactoringEngine()->startLocalRenaming(textCursor(),
|
||||
textDocument()->filePath(),
|
||||
document()->revision(),
|
||||
projectPart(),
|
||||
std::move(renameSymbols));
|
||||
|
||||
viewport()->setCursor(Qt::BusyCursor);
|
||||
}
|
||||
}
|
||||
|
||||
void CppEditorWidget::updatePreprocessorButtonTooltip()
|
||||
{
|
||||
QTC_ASSERT(d->m_preprocessorButton, return);
|
||||
@@ -500,6 +638,11 @@ RefactorMarkers CppEditorWidget::refactorMarkersWithoutClangMarkers() const
|
||||
return clearedRefactorMarkers;
|
||||
}
|
||||
|
||||
RefactoringEngineInterface *CppEditorWidget::refactoringEngine() const
|
||||
{
|
||||
return CppTools::CppModelManager::refactoringEngine();
|
||||
}
|
||||
|
||||
bool CppEditorWidget::isSemanticInfoValidExceptLocalUses() const
|
||||
{
|
||||
return d->m_lastSemanticInfo.doc
|
||||
|
||||
Reference in New Issue
Block a user