Clang: Add clang query

Clang query is mechanism to use AST matcher to search for code. Think
about regular expression but in the context of AST. So you get a semantic
search tool for C++.

Change-Id: I72e882c5b53a0c52f352a3664847c4c3e4f6fc2e
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Tim Jenssen
2016-11-15 15:38:12 +01:00
parent 96187594b5
commit 9c7ff5199f
99 changed files with 4603 additions and 246 deletions

View File

@@ -26,6 +26,7 @@
#include "refactoringclient.h"
#include <sourcelocationsforrenamingmessage.h>
#include <sourcerangesanddiagnosticsforquerymessage.h>
namespace ClangRefactoring {
@@ -34,7 +35,8 @@ void RefactoringClient::alive()
}
void RefactoringClient::sourceLocationsForRenamingMessage(ClangBackEnd::SourceLocationsForRenamingMessage &&message)
void RefactoringClient::sourceLocationsForRenamingMessage(
ClangBackEnd::SourceLocationsForRenamingMessage &&message)
{
localRenamingCallback(message.symbolName().toQString(),
message.sourceLocations(),
@@ -43,7 +45,15 @@ void RefactoringClient::sourceLocationsForRenamingMessage(ClangBackEnd::SourceLo
refactoringEngine->setUsable(true);
}
void RefactoringClient::setLocalRenamingCallback(CppTools::RefactoringEngineInterface::RenameCallback &&localRenamingCallback)
void RefactoringClient::sourceRangesAndDiagnosticsForQueryMessage(
ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage &&message)
{
addSearchResults(message.sourceRanges());
sendSearchIsFinished();
}
void RefactoringClient::setLocalRenamingCallback(
CppTools::RefactoringEngineInterface::RenameCallback &&localRenamingCallback)
{
this->localRenamingCallback = std::move(localRenamingCallback);
}
@@ -53,9 +63,75 @@ void RefactoringClient::setRefactoringEngine(RefactoringEngine *refactoringEngin
this->refactoringEngine = refactoringEngine;
}
void RefactoringClient::setSearchHandle(SearchHandleInterface *searchHandleInterface)
{
this->searchHandleInterface = searchHandleInterface;
}
SearchHandleInterface *RefactoringClient::searchHandle() const
{
return searchHandleInterface;
}
bool RefactoringClient::hasValidLocalRenamingCallback() const
{
return bool(localRenamingCallback);
}
namespace {
Utils::SmallString concatenateFilePath(const ClangBackEnd::FilePath &filePath)
{
Utils::SmallString concatenatedFilePath = filePath.directory().clone();
concatenatedFilePath.append("/");
concatenatedFilePath.append(filePath.name().clone());
return concatenatedFilePath;
}
}
std::unordered_map<uint, QString> RefactoringClient::convertFilePaths(
const ClangBackEnd::FilePathDict &filePaths)
{
using Dict = std::unordered_map<uint, QString>;
Dict qstringFilePaths;
qstringFilePaths.reserve(filePaths.size());
auto convertFilePath = [] (const ClangBackEnd::FilePathDict::value_type &dictonaryEntry) {
return std::make_pair(dictonaryEntry.first,
concatenateFilePath(dictonaryEntry.second).toQString());
};
std::transform(filePaths.begin(),
filePaths.end(),
std::inserter(qstringFilePaths, qstringFilePaths.begin()),
convertFilePath);
return qstringFilePaths;
}
void RefactoringClient::addSearchResults(const ClangBackEnd::SourceRangesContainer &sourceRanges)
{
auto filePaths = convertFilePaths(sourceRanges.filePaths());
for (const auto &sourceRangeWithText : sourceRanges.sourceRangeWithTextContainers())
addSearchResult(sourceRangeWithText, filePaths);
}
void RefactoringClient::addSearchResult(const ClangBackEnd::SourceRangeWithTextContainer &sourceRangeWithText,
std::unordered_map<uint, QString> &filePaths)
{
searchHandleInterface->addResult(filePaths[sourceRangeWithText.fileHash()],
int(sourceRangeWithText.start().line()),
sourceRangeWithText.text(),
int(sourceRangeWithText.start().column()),
int(sourceRangeWithText.end().column()));
}
void RefactoringClient::sendSearchIsFinished()
{
searchHandleInterface->finishSearch();
}
} // namespace ClangRefactoring