ClangCodeModel: Replace FilePath::toString

Replace occurrences of FilePath::toString with more sensible alternatives.
Use FilePath capabilities instead of QDir/QFile's where applicable.
Use FilePath instead of QString where it makes sense.
Avoid excessive copies.
Add function overloads taking FilePath to CppEditor::ProjectFile.

Change-Id: I63e194a6d9e88052024c17d704940eab2803e7bf
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Andrii Semkiv
2024-09-09 13:34:34 +02:00
committed by andrii.semkiv
parent eee38e585e
commit 887b65bcc3
8 changed files with 71 additions and 41 deletions

View File

@@ -383,7 +383,7 @@ static void addToCompilationDb(QJsonObject &cdb,
const QString fileString = sourceFile.path.toUserOutput(); const QString fileString = sourceFile.path.toUserOutput();
args.append(fileString); args.append(fileString);
QJsonObject value; QJsonObject value;
value.insert("workingDirectory", workingDir.toString()); value.insert("workingDirectory", workingDir.path());
value.insert("compilationCommand", args); value.insert("compilationCommand", args);
cdb.insert(fileString, value); cdb.insert(fileString, value);
} }
@@ -520,13 +520,20 @@ void ClangdClient::openExtraFile(const Utils::FilePath &filePath, const QString
return; return;
} }
QFile cxxFile(filePath.toString()); QString text;
if (content.isEmpty() && !cxxFile.open(QIODevice::ReadOnly)) if (!content.isEmpty()) {
return; text = content;
} else {
expected_str<QByteArray> fileContent = filePath.fileContents();
if (!fileContent)
return;
text = QString::fromUtf8(*std::move(fileContent));
}
TextDocumentItem item; TextDocumentItem item;
item.setLanguageId("cpp"); item.setLanguageId("cpp");
item.setUri(hostPathToServerUri(filePath)); item.setUri(hostPathToServerUri(filePath));
item.setText(!content.isEmpty() ? content : QString::fromUtf8(cxxFile.readAll())); item.setText(std::move(text));
item.setVersion(0); item.setVersion(0);
sendMessage(DidOpenTextDocumentNotification(DidOpenTextDocumentParams(item)), sendMessage(DidOpenTextDocumentNotification(DidOpenTextDocumentParams(item)),
SendDocUpdates::Ignore); SendDocUpdates::Ignore);
@@ -918,8 +925,7 @@ void ClangdClient::updateParserConfig(const Utils::FilePath &filePath,
CppEditor::CompilerOptionsBuilder optionsBuilder = clangOptionsBuilder( CppEditor::CompilerOptionsBuilder optionsBuilder = clangOptionsBuilder(
*projectPart, warningsConfigForProject(project()), includeDir, *projectPart, warningsConfigForProject(project()), includeDir,
ProjectExplorer::Macro::toMacros(config.editorDefines)); ProjectExplorer::Macro::toMacros(config.editorDefines));
const CppEditor::ProjectFile file(filePath, const CppEditor::ProjectFile file(filePath, CppEditor::ProjectFile::classify(filePath));
CppEditor::ProjectFile::classify(filePath.toString()));
const QJsonArray projectPartOptions = fullProjectPartOptions( const QJsonArray projectPartOptions = fullProjectPartOptions(
optionsBuilder, globalClangOptions()); optionsBuilder, globalClangOptions());
const auto cppSettings = CppEditor::CppCodeModelSettings::settingsForProject( const auto cppSettings = CppEditor::CppCodeModelSettings::settingsForProject(

View File

@@ -321,7 +321,7 @@ bool ClangdCompletionAssistProvider::isContinuationChar(const QChar &c) const
bool ClangdCompletionAssistProvider::isInCommentOrString(const AssistInterface *interface) const bool ClangdCompletionAssistProvider::isInCommentOrString(const AssistInterface *interface) const
{ {
LanguageFeatures features = LanguageFeatures::defaultFeatures(); LanguageFeatures features = LanguageFeatures::defaultFeatures();
features.objCEnabled = ProjectFile::isObjC(interface->filePath().toString()); features.objCEnabled = ProjectFile::isObjC(interface->filePath());
return CppEditor::isInCommentOrString(interface, features); return CppEditor::isInCommentOrString(interface, features);
} }
@@ -543,7 +543,7 @@ IAssistProposal *CustomAssistProcessor::perform()
: CppCompletionAssistProcessor::preprocessorCompletions()) { : CppCompletionAssistProcessor::preprocessorCompletions()) {
completions << createItem(completion, macroIcon); completions << createItem(completion, macroIcon);
} }
if (ProjectFile::isObjC(interface()->filePath().toString())) if (ProjectFile::isObjC(interface()->filePath()))
completions << createItem("import", macroIcon); completions << createItem("import", macroIcon);
break; break;
} }

View File

@@ -191,22 +191,23 @@ ClangdFindReferences::ClangdFindReferences(ClangdClient *client, const Link &lin
d->categorize = true; d->categorize = true;
d->search = search; d->search = search;
if (!client->documentForFilePath(link.targetFilePath)) { const FilePath &targetFilePath = link.targetFilePath;
QFile f(link.targetFilePath.toString()); if (!client->documentForFilePath(targetFilePath)) {
if (!f.open(QIODevice::ReadOnly)) { expected_str<QByteArray> fileContents = targetFilePath.fileContents();
if (!fileContents) {
d->finishSearch(); d->finishSearch();
return; return;
} }
const QString contents = QString::fromUtf8(f.readAll()); const QString contents = QString::fromUtf8(*std::move(fileContents));
QTextDocument doc(contents); QTextDocument doc(contents);
QTextCursor cursor(&doc); QTextCursor cursor(&doc);
cursor.setPosition(Text::positionInText(&doc, link.targetLine, link.targetColumn + 1)); cursor.setPosition(Text::positionInText(&doc, link.targetLine, link.targetColumn + 1));
cursor.select(QTextCursor::WordUnderCursor); cursor.select(QTextCursor::WordUnderCursor);
d->searchTerm = cursor.selectedText(); d->searchTerm = cursor.selectedText();
client->openExtraFile(link.targetFilePath, contents); client->openExtraFile(targetFilePath, contents);
d->checkUnusedData->openedExtraFileForLink = true; d->checkUnusedData->openedExtraFileForLink = true;
} }
const TextDocumentIdentifier documentId(client->hostPathToServerUri(link.targetFilePath)); const TextDocumentIdentifier documentId(client->hostPathToServerUri(targetFilePath));
const Position pos(link.targetLine - 1, link.targetColumn); const Position pos(link.targetLine - 1, link.targetColumn);
ReferenceParams params(TextDocumentPositionParams(documentId, pos)); ReferenceParams params(TextDocumentPositionParams(documentId, pos));
params.setContext(ReferenceParams::ReferenceContext(true)); params.setContext(ReferenceParams::ReferenceContext(true));

View File

@@ -31,11 +31,11 @@ namespace {
const char LINK_ACTION_GOTO_LOCATION[] = "#gotoLocation"; const char LINK_ACTION_GOTO_LOCATION[] = "#gotoLocation";
const char LINK_ACTION_APPLY_FIX[] = "#applyFix"; const char LINK_ACTION_APPLY_FIX[] = "#applyFix";
QString fileNamePrefix(const QString &mainFilePath, const Utils::Link &location) QString fileNamePrefix(const Utils::FilePath &mainFilePath, const Utils::Link &location)
{ {
const QString filePath = location.targetFilePath.toString(); const Utils::FilePath &filePath = location.targetFilePath;
if (!filePath.isEmpty() && filePath != mainFilePath) if (!filePath.isEmpty() && filePath != mainFilePath)
return QFileInfo(filePath).fileName() + QLatin1Char(':'); return filePath.fileName() + QLatin1Char(':');
return QString(); return QString();
} }
@@ -175,8 +175,8 @@ private:
QString tableRows(const ClangDiagnostic &diagnostic) QString tableRows(const ClangDiagnostic &diagnostic)
{ {
m_mainFilePath = m_displayHints.showFileNameInMainDiagnostic m_mainFilePath = m_displayHints.showFileNameInMainDiagnostic
? QString() ? Utils::FilePath{}
: diagnostic.location.targetFilePath.toString(); : diagnostic.location.targetFilePath;
const ClangDiagnostic diag = supplementedDiagnostic(diagnostic); const ClangDiagnostic diag = supplementedDiagnostic(diagnostic);
@@ -253,8 +253,8 @@ private:
return text; return text;
} }
QString clickableLocation(const ClangDiagnostic &diagnostic, const QString &mainFilePath, QString clickableLocation(
bool &hasContent) const ClangDiagnostic &diagnostic, const Utils::FilePath &mainFilePath, bool &hasContent)
{ {
const Utils::Link &location = diagnostic.location; const Utils::Link &location = diagnostic.location;
@@ -331,7 +331,7 @@ private:
TargetIdToDiagnosticTable m_targetIdsToDiagnostics; TargetIdToDiagnosticTable m_targetIdsToDiagnostics;
unsigned m_targetIdCounter = 0; unsigned m_targetIdCounter = 0;
QString m_mainFilePath; Utils::FilePath m_mainFilePath;
}; };
WidgetFromDiagnostics::DisplayHints toHints(const ClangDiagnosticWidget::Destination &destination, WidgetFromDiagnostics::DisplayHints toHints(const ClangDiagnosticWidget::Destination &destination,

View File

@@ -13,7 +13,7 @@
namespace ClangCodeModel { namespace ClangCodeModel {
namespace Internal { namespace Internal {
using FileToFixits = QMap<QString, QList<ClangFixIt>>; using FileToFixits = QMap<Utils::FilePath, QList<ClangFixIt>>;
using RefactoringFilePtr = QSharedPointer<TextEditor::RefactoringFile>; using RefactoringFilePtr = QSharedPointer<TextEditor::RefactoringFile>;
ClangFixItOperation::ClangFixItOperation(const QString &fixItText, const QList<ClangFixIt> &fixIts) ClangFixItOperation::ClangFixItOperation(const QString &fixItText, const QList<ClangFixIt> &fixIts)
@@ -36,8 +36,8 @@ static FileToFixits fixitsPerFile(const QList<ClangFixIt> &fixIts)
FileToFixits mapping; FileToFixits mapping;
for (const auto &fixItContainer : fixIts) { for (const auto &fixItContainer : fixIts) {
const QString rangeStartFilePath = fixItContainer.range.start.targetFilePath.toString(); const Utils::FilePath &rangeStartFilePath = fixItContainer.range.start.targetFilePath;
const QString rangeEndFilePath = fixItContainer.range.end.targetFilePath.toString(); const Utils::FilePath &rangeEndFilePath = fixItContainer.range.end.targetFilePath;
QTC_CHECK(rangeStartFilePath == rangeEndFilePath); QTC_CHECK(rangeStartFilePath == rangeEndFilePath);
mapping[rangeStartFilePath].append(fixItContainer); mapping[rangeStartFilePath].append(fixItContainer);
} }
@@ -52,11 +52,10 @@ void ClangFixItOperation::perform()
const FileToFixits fileToFixIts = fixitsPerFile(fixIts); const FileToFixits fileToFixIts = fixitsPerFile(fixIts);
for (auto i = fileToFixIts.cbegin(), end = fileToFixIts.cend(); i != end; ++i) { for (auto i = fileToFixIts.cbegin(), end = fileToFixIts.cend(); i != end; ++i) {
const QString filePath = i.key(); const Utils::FilePath &filePath = i.key();
const QList<ClangFixIt> fixits = i.value(); const QList<ClangFixIt> &fixits = i.value();
RefactoringFilePtr refactoringFile = refactoringChanges.file( RefactoringFilePtr refactoringFile = refactoringChanges.file(filePath);
Utils::FilePath::fromString(filePath));
refactoringFiles.append(refactoringFile); refactoringFiles.append(refactoringFile);
applyFixitsToFile(*refactoringFile, fixits); applyFixitsToFile(*refactoringFile, fixits);

View File

@@ -800,7 +800,7 @@ void ClangModelManagerSupport::watchForExternalChanges()
if (!LanguageClientManager::hasClients<ClangdClient>()) if (!LanguageClientManager::hasClients<ClangdClient>())
return; return;
for (const FilePath &file : files) { for (const FilePath &file : files) {
const ProjectFile::Kind kind = ProjectFile::classify(file.toString()); const ProjectFile::Kind kind = ProjectFile::classify(file);
if (!ProjectFile::isSource(kind) && !ProjectFile::isHeader(kind)) if (!ProjectFile::isSource(kind) && !ProjectFile::isHeader(kind))
continue; continue;
Project * const project = ProjectManager::projectForFile(file); Project * const project = ProjectManager::projectForFile(file);
@@ -842,7 +842,7 @@ void ClangModelManagerSupport::watchForInternalChanges()
connect(DocumentManager::instance(), &DocumentManager::filesChangedInternally, connect(DocumentManager::instance(), &DocumentManager::filesChangedInternally,
this, [this](const FilePaths &filePaths) { this, [this](const FilePaths &filePaths) {
for (const FilePath &fp : filePaths) { for (const FilePath &fp : filePaths) {
const ProjectFile::Kind kind = ProjectFile::classify(fp.toString()); const ProjectFile::Kind kind = ProjectFile::classify(fp);
if (!ProjectFile::isSource(kind) && !ProjectFile::isHeader(kind)) if (!ProjectFile::isSource(kind) && !ProjectFile::isHeader(kind))
continue; continue;
Project * const project = ProjectManager::projectForFile(fp); Project * const project = ProjectManager::projectForFile(fp);

View File

@@ -11,6 +11,16 @@
namespace CppEditor { namespace CppEditor {
template<typename T>
static ProjectFile::Kind classifyImpl(T &&file)
{
if (ProjectFile::isAmbiguousHeader(file))
return ProjectFile::Kind::AmbiguousHeader;
const Utils::MimeType mimeType = Utils::mimeTypeForFile(file);
return ProjectFile::classifyByMimeType(mimeType.name());
}
ProjectFile::ProjectFile(const Utils::FilePath &filePath, Kind kind, bool active) ProjectFile::ProjectFile(const Utils::FilePath &filePath, Kind kind, bool active)
: path(filePath) : path(filePath)
, kind(kind) , kind(kind)
@@ -53,16 +63,22 @@ ProjectFile::Kind ProjectFile::classifyByMimeType(const QString &mt)
ProjectFile::Kind ProjectFile::classify(const QString &filePath) ProjectFile::Kind ProjectFile::classify(const QString &filePath)
{ {
if (isAmbiguousHeader(filePath)) return classifyImpl(filePath);
return AmbiguousHeader;
const Utils::MimeType mimeType = Utils::mimeTypeForFile(filePath);
return classifyByMimeType(mimeType.name());
} }
bool ProjectFile::isAmbiguousHeader(const QString &filePath) ProjectFile::Kind ProjectFile::classify(const Utils::FilePath &filePath)
{ {
return filePath.endsWith(".h"); return classifyImpl(filePath);
}
bool ProjectFile::isAmbiguousHeader(QStringView filePath)
{
return filePath.endsWith(u".h");
}
bool ProjectFile::isAmbiguousHeader(const Utils::FilePath &filePath)
{
return isAmbiguousHeader(filePath.fileNameView());
} }
bool ProjectFile::isObjC(const QString &filePath) bool ProjectFile::isObjC(const QString &filePath)
@@ -70,6 +86,11 @@ bool ProjectFile::isObjC(const QString &filePath)
return isObjC(classify(filePath)); return isObjC(classify(filePath));
} }
bool ProjectFile::isObjC(const Utils::FilePath &filePath)
{
return isObjC(classify(filePath));
}
bool ProjectFile::isObjC(Kind kind) bool ProjectFile::isObjC(Kind kind)
{ {
switch (kind) { switch (kind) {
@@ -131,7 +152,7 @@ bool ProjectFile::isHeader(ProjectFile::Kind kind)
bool ProjectFile::isHeader(const Utils::FilePath &fp) bool ProjectFile::isHeader(const Utils::FilePath &fp)
{ {
return isHeader(classify(fp.toString())); return isHeader(classify(fp));
} }
bool ProjectFile::isSource(ProjectFile::Kind kind) bool ProjectFile::isSource(ProjectFile::Kind kind)

View File

@@ -35,6 +35,7 @@ public:
static Kind classifyByMimeType(const QString &mt); static Kind classifyByMimeType(const QString &mt);
static Kind classify(const QString &filePath); static Kind classify(const QString &filePath);
static Kind classify(const Utils::FilePath &filePath);
static Kind sourceForHeaderKind(Kind kind); static Kind sourceForHeaderKind(Kind kind);
static Kind sourceKind(Kind kind); static Kind sourceKind(Kind kind);
@@ -44,8 +45,10 @@ public:
static bool isHeader(const Utils::FilePath &fp); static bool isHeader(const Utils::FilePath &fp);
static bool isC(Kind kind); static bool isC(Kind kind);
static bool isCxx(Kind kind); static bool isCxx(Kind kind);
static bool isAmbiguousHeader(const QString &filePath); static bool isAmbiguousHeader(QStringView filePath);
static bool isAmbiguousHeader(const Utils::FilePath &filePath);
static bool isObjC(const QString &filePath); static bool isObjC(const QString &filePath);
static bool isObjC(const Utils::FilePath &filePath);
static bool isObjC(Kind kind); static bool isObjC(Kind kind);
bool isHeader() const; bool isHeader() const;