refactor: Extract document reading to separate class (#127)

This decouples LLMClientInterface from Qt Creator text editor
implementation and allows to write tests
This commit is contained in:
Povilas Kanapickas 2025-03-10 18:42:40 +02:00 committed by GitHub
parent a218064a4f
commit 719065ebfc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 99 additions and 7 deletions

View File

@ -23,8 +23,6 @@
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <texteditor/textdocument.h>
#include "CodeHandler.hpp"
#include "context/ContextManager.hpp"
#include "context/DocumentContextReader.hpp"
@ -44,12 +42,14 @@ LLMClientInterface::LLMClientInterface(
LLMCore::IProviderRegistry &providerRegistry,
LLMCore::IPromptProvider *promptProvider,
LLMCore::RequestHandlerBase &requestHandler,
Context::IDocumentReader &documentReader,
IRequestPerformanceLogger &performanceLogger)
: m_generalSettings(generalSettings)
, m_completeSettings(completeSettings)
, m_providerRegistry(providerRegistry)
, m_promptProvider(promptProvider)
, m_requestHandler(requestHandler)
, m_documentReader(documentReader)
, m_performanceLogger(performanceLogger)
{
connect(
@ -261,12 +261,10 @@ LLMCore::ContextData LLMClientInterface::prepareContext(
QJsonObject params = request["params"].toObject();
QJsonObject doc = params["doc"].toObject();
QJsonObject position = doc["position"].toObject();
auto filePath = Context::extractFilePathFromRequest(request);
TextEditor::TextDocument *textDocument = TextEditor::TextDocument::textDocumentForFilePath(
Utils::FilePath::fromString(filePath));
if (!textDocument) {
auto documentInfo = m_documentReader.readDocument(filePath);
if (!documentInfo.document) {
LOG_MESSAGE("Error: Document is not available for" + filePath);
return LLMCore::ContextData{};
}
@ -275,7 +273,7 @@ LLMCore::ContextData LLMClientInterface::prepareContext(
int lineNumber = position["line"].toInt();
Context::DocumentContextReader
reader(textDocument->document(), textDocument->mimeType(), filePath);
reader(documentInfo.document, documentInfo.mimeType, documentInfo.filePath);
return reader.prepareContext(lineNumber, cursorPosition, m_completeSettings);
}

View File

@ -22,6 +22,7 @@
#include <languageclient/languageclientinterface.h>
#include <texteditor/texteditor.h>
#include <context/IDocumentReader.hpp>
#include <context/ProgrammingLanguage.hpp>
#include <llmcore/ContextData.hpp>
#include <llmcore/IPromptProvider.hpp>
@ -47,6 +48,7 @@ public:
LLMCore::IProviderRegistry &providerRegistry,
LLMCore::IPromptProvider *promptProvider,
LLMCore::RequestHandlerBase &requestHandler,
Context::IDocumentReader &documentReader,
IRequestPerformanceLogger &performanceLogger);
Utils::FilePath serverDeviceTemplate() const override;
@ -77,6 +79,7 @@ private:
LLMCore::IPromptProvider *m_promptProvider = nullptr;
LLMCore::IProviderRegistry &m_providerRegistry;
LLMCore::RequestHandlerBase &m_requestHandler;
Context::IDocumentReader &m_documentReader;
IRequestPerformanceLogger &m_performanceLogger;
QElapsedTimer m_completionTimer;
};

View File

@ -3,6 +3,8 @@ add_library(Context STATIC
ChangesManager.h ChangesManager.cpp
ContextManager.hpp ContextManager.cpp
ContentFile.hpp
DocumentReaderQtCreator.hpp
IDocumentReader.hpp
TokenUtils.hpp TokenUtils.cpp
ProgrammingLanguage.hpp ProgrammingLanguage.cpp
)

View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2025 Povilas Kanapickas
*
* This file is part of QodeAssist.
*
* QodeAssist is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QodeAssist is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QodeAssist. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "IDocumentReader.hpp"
#include <texteditor/textdocument.h>
namespace QodeAssist::Context {
class DocumentReaderQtCreator : public IDocumentReader
{
public:
DocumentInfo readDocument(const QString &path) const override
{
auto *textDocument = TextEditor::TextDocument::textDocumentForFilePath(
Utils::FilePath::fromString(path));
if (!textDocument) {
return {};
}
return {
.document = textDocument->document(),
.mimeType = textDocument->mimeType(),
.filePath = path};
}
};
} // namespace QodeAssist::Context

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2025 Povilas Kanapickas
*
* This file is part of QodeAssist.
*
* QodeAssist is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QodeAssist is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QodeAssist. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <QTextDocument>
namespace QodeAssist::Context {
struct DocumentInfo
{
QTextDocument *document = nullptr; // not owned
QString mimeType;
QString filePath;
};
class IDocumentReader
{
public:
virtual ~IDocumentReader() = default;
virtual DocumentInfo readDocument(const QString &path) const = 0;
};
} // namespace QodeAssist::Context

View File

@ -46,6 +46,7 @@
#include "Version.hpp"
#include "chat/ChatOutputPane.h"
#include "chat/NavigationPanel.hpp"
#include "context/DocumentReaderQtCreator.hpp"
#include "llmcore/PromptProviderFim.hpp"
#include "llmcore/ProvidersManager.hpp"
#include "logger/RequestPerformanceLogger.hpp"
@ -146,6 +147,7 @@ public:
LLMCore::ProvidersManager::instance(),
&m_promptProvider,
m_requestHandler,
m_documentReader,
m_performanceLogger));
}
@ -189,6 +191,7 @@ private:
QPointer<QodeAssistClient> m_qodeAssistClient;
LLMCore::PromptProviderFim m_promptProvider;
LLMCore::RequestHandler m_requestHandler{this};
Context::DocumentReaderQtCreator m_documentReader;
RequestPerformanceLogger m_performanceLogger;
QPointer<Chat::ChatOutputPane> m_chatOutputPane;
QPointer<Chat::NavigationPanel> m_navigationPanel;