diff options
author | Marco Bubke <marco.bubke@qt.io> | 2016-08-04 15:26:53 +0200 |
---|---|---|
committer | Marco Bubke <marco.bubke@qt.io> | 2016-08-04 14:37:19 +0000 |
commit | 4cdb5bab157bfec52ece3a2ed6dd1ace82f80265 (patch) | |
tree | 091c985e8ffcb17171475239e7838ad3b20cbbb4 /src/plugins/cppeditor | |
parent | 2b9edb35ea85e3fdc56f112d7d73021ea47ece08 (diff) | |
download | qt-creator-4cdb5bab157bfec52ece3a2ed6dd1ace82f80265.tar.gz |
Clang: Add clang refactoring
Change-Id: I2e3f36f810276da3f8dc7dcc587b06f8edb586d3
GPush-Base: d02f51b48fc752fddcdef6dcb32b3f7f6c0195a3
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
Diffstat (limited to 'src/plugins/cppeditor')
-rw-r--r-- | src/plugins/cppeditor/cppeditor.cpp | 143 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppeditor.h | 9 |
2 files changed, 152 insertions, 0 deletions
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index b5e6f9657d..63d964af9e 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -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> @@ -378,7 +384,16 @@ 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 diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h index 9f43890c79..626b16ab94 100644 --- a/src/plugins/cppeditor/cppeditor.h +++ b/src/plugins/cppeditor/cppeditor.h @@ -33,7 +33,9 @@ namespace CppTools { class CppEditorOutline; +class RefactoringEngineInterface; class SemanticInfo; +class ProjectPart; } namespace CppEditor { @@ -135,6 +137,13 @@ private: TextEditor::RefactorMarkers refactorMarkersWithoutClangMarkers() const; + CppTools::RefactoringEngineInterface *refactoringEngine() const; + + void renameSymbolUnderCursorClang(); + void renameSymbolUnderCursorBuiltin(); + + CppTools::ProjectPart *projectPart() const; + private: QScopedPointer<CppEditorWidgetPrivate> d; }; |