♻️ 使用module重构所有代码

This commit is contained in:
csh
2025-12-07 23:07:03 +08:00
parent 549f1d1b0a
commit f7d5a74615
369 changed files with 2272844 additions and 2202476 deletions
@@ -1,6 +1,22 @@
#include "bootstrap.hpp"
#include <spdlog/spdlog.h>
#include "../utils/args_parser.hpp"
module;
#include <format>
export module lsp.manager.bootstrap;
import spdlog;
import std;
import lsp.manager.manager_hub;
import lsp.scheduler.async_executor;
import lsp.utils.args_parser;
export namespace lsp::manager::bootstrap
{
void InitializeManagerHub(
ManagerHub& hub,
scheduler::AsyncExecutor& async_executor,
const std::vector<std::string>& system_lib_paths);
}
namespace lsp::manager::bootstrap
{
@@ -13,7 +29,7 @@ namespace lsp::manager::bootstrap
for (const auto& path : system_lib_paths)
{
std::string task_name = fmt::format("Load system library: {}", path);
std::string task_name = std::format("Load system library: {}", path);
async_executor.Submit(
task_name,
@@ -21,7 +37,7 @@ namespace lsp::manager::bootstrap
try
{
hub.symbols().LoadSystemLibrary(path);
return fmt::format("Loaded system library: {}", path);
return std::format("Loaded system library: {}", path);
}
catch (const std::exception& e)
{
-11
View File
@@ -1,11 +0,0 @@
#pragma once
#include "../manager/manager_hub.hpp"
#include "../scheduler/async_executor.hpp"
namespace lsp::manager::bootstrap
{
void InitializeManagerHub(
ManagerHub& hub,
scheduler::AsyncExecutor& async_executor,
const std::vector<std::string>& system_lib_paths);
}
@@ -1,6 +1,34 @@
#include "text_document.hpp"
#include <spdlog/spdlog.h>
#include "../../utils/text_coordinates.hpp"
module;
export module lsp.manager.detail.text_document;
import tree_sitter;
import spdlog;
import std;
import lsp.protocol;
import lsp.utils.text_coordinates;
export namespace lsp::manager::detail
{
class TextDocument
{
public:
explicit TextDocument(const protocol::TextDocumentItem& item);
void ApplyChange(const protocol::TextDocumentContentChangeEvent& change);
void SetVersion(protocol::integer version);
const protocol::string& GetContent() const;
const protocol::DocumentUri& GetUri() const;
protocol::integer GetVersion() const;
private:
static bool IsFullDocumentUpdate(const protocol::TextDocumentContentChangeEvent& change, const protocol::string& current_content);
protocol::TextDocumentItem item_;
};
}
namespace lsp::manager::detail
{
@@ -47,7 +75,7 @@ namespace lsp::manager::detail
if (change.range.start.line == 0 && change.range.start.character == 0)
{
protocol::uinteger line_count = 0;
for (size_t i = 0; i < current_content.length(); ++i)
for (std::size_t i = 0; i < current_content.length(); ++i)
{
if (current_content[i] == '\n')
line_count++;
@@ -1,27 +0,0 @@
#pragma once
#include "../../protocol/protocol.hpp"
extern "C" {
#include <tree_sitter/api.h>
}
namespace lsp::manager::detail
{
class TextDocument
{
public:
explicit TextDocument(const protocol::TextDocumentItem& item);
void ApplyChange(const protocol::TextDocumentContentChangeEvent& change);
void SetVersion(protocol::integer version);
const protocol::string& GetContent() const;
const protocol::DocumentUri& GetUri() const;
protocol::integer GetVersion() const;
private:
static bool IsFullDocumentUpdate(const protocol::TextDocumentContentChangeEvent& change, const protocol::string& current_content);
protocol::TextDocumentItem item_;
};
}
@@ -1,6 +1,39 @@
#include "document.hpp"
#include <spdlog/spdlog.h>
#include "./events.hpp"
module;
export module lsp.manager.document;
import spdlog;
import std;
import lsp.protocol;
import lsp.manager.event_bus;
import lsp.manager.detail.text_document;
import lsp.manager.events;
export namespace lsp::manager
{
class Document
{
public:
explicit Document(EventBus& event_bus);
~Document();
void OpenDocument(const protocol::DidOpenTextDocumentParams& params);
void UpdateDocument(const protocol::DidChangeTextDocumentParams& params);
void CloseDocument(const protocol::DidCloseTextDocumentParams& params);
std::optional<protocol::string> GetContent(const protocol::DocumentUri& uri) const;
std::optional<protocol::integer> GetVersion(const protocol::DocumentUri& uri) const;
std::vector<protocol::DocumentUri> GetAllDocumentUris() const;
void Clear();
private:
mutable std::shared_mutex mutex_;
std::unordered_map<protocol::DocumentUri, detail::TextDocument> documents_;
EventBus& event_bus_;
};
}
namespace lsp::manager
{
-33
View File
@@ -1,33 +0,0 @@
#pragma once
#include <memory>
#include <unordered_map>
#include <shared_mutex>
#include "./event_bus.hpp"
#include "./detail/text_document.hpp"
#include "../protocol/protocol.hpp"
namespace lsp::manager
{
class Document
{
public:
explicit Document(EventBus& event_bus);
~Document();
void OpenDocument(const protocol::DidOpenTextDocumentParams& params);
void UpdateDocument(const protocol::DidChangeTextDocumentParams& params);
void CloseDocument(const protocol::DidCloseTextDocumentParams& params);
std::optional<protocol::string> GetContent(const protocol::DocumentUri& uri) const;
std::optional<protocol::integer> GetVersion(const protocol::DocumentUri& uri) const;
std::vector<protocol::DocumentUri> GetAllDocumentUris() const;
void Clear();
private:
mutable std::shared_mutex mutex_;
std::unordered_map<protocol::DocumentUri, detail::TextDocument> documents_;
EventBus& event_bus_;
};
}
@@ -1,13 +1,10 @@
#pragma once
module;
#include <functional>
#include <mutex>
#include <shared_mutex>
#include <typeindex>
#include <unordered_map>
#include <vector>
export module lsp.manager.event_bus;
namespace lsp::manager
import std;
export namespace lsp::manager
{
class EventBus
{
@@ -46,10 +43,10 @@ namespace lsp::manager
handlers_.erase(type);
}
size_t GetSubscriberCount() const
std::size_t GetSubscriberCount() const
{
std::shared_lock<std::shared_mutex> lock(mutex_);
size_t count = 0;
std::size_t count = 0;
for (const auto& [type, handlers] : handlers_)
count += handlers.size();
return count;
@@ -1,12 +1,14 @@
#pragma once
module;
#include "../protocol/protocol.hpp"
extern "C" {
#include <tree_sitter/api.h>
}
export module lsp.manager.events;
import tree_sitter;
namespace lsp::manager::events
import std;
import lsp.protocol;
export namespace lsp::manager::events
{
using DocumentOpened = protocol::DidOpenTextDocumentParams;
using DocumentClosed = protocol::DidCloseTextDocumentParams;
-29
View File
@@ -1,29 +0,0 @@
#include "manager_hub.hpp"
#include <algorithm>
#include "../utils/text_coordinates.hpp"
namespace lsp::manager
{
ManagerHub::ManagerHub() : event_bus_(),
documents_(event_bus_),
parser_(event_bus_),
symbols_(event_bus_)
{
}
ManagerHub::~ManagerHub() = default;
void ManagerHub::Initialize()
{
documents_.Clear();
parser_.Clear();
}
void ManagerHub::Shutdown()
{
documents_.Clear();
parser_.Clear();
}
}
+60
View File
@@ -0,0 +1,60 @@
module;
export module lsp.manager.manager_hub;
import std;
import lsp.protocol;
import lsp.manager.event_bus;
import lsp.manager.document;
import lsp.manager.parser;
import lsp.manager.symbol;
import lsp.utils.text_coordinates;
export namespace lsp::manager
{
class ManagerHub
{
public:
ManagerHub();
~ManagerHub();
void Initialize();
void Shutdown();
Document& documents() { return documents_; }
Parser& parser() { return parser_; }
Symbol& symbols() { return symbols_; }
private:
EventBus event_bus_;
Document documents_;
Parser parser_;
Symbol symbols_;
};
}
namespace lsp::manager
{
ManagerHub::ManagerHub() : event_bus_(),
documents_(event_bus_),
parser_(event_bus_),
symbols_(event_bus_)
{
}
ManagerHub::~ManagerHub() = default;
void ManagerHub::Initialize()
{
documents_.Clear();
parser_.Clear();
}
void ManagerHub::Shutdown()
{
documents_.Clear();
parser_.Clear();
}
}
-34
View File
@@ -1,34 +0,0 @@
#pragma once
#include <optional>
#include <string>
#include "../manager/event_bus.hpp"
#include "../manager/document.hpp"
#include "../manager/parser.hpp"
#include "../manager/symbol.hpp"
#include "../protocol/protocol.hpp"
namespace lsp::manager
{
class ManagerHub
{
public:
ManagerHub();
~ManagerHub();
void Initialize();
void Shutdown();
Document& documents() { return documents_; }
Parser& parser() { return parser_; }
Symbol& symbols() { return symbols_; }
private:
EventBus event_bus_;
Document documents_;
Parser parser_;
Symbol symbols_;
};
}
@@ -1,6 +1,72 @@
#include "parser.hpp"
#include <spdlog/spdlog.h>
#include "../utils/text_coordinates.hpp"
module;
export module lsp.manager.parser;
import tree_sitter;
import spdlog;
import std;
import lsp.protocol;
import lsp.manager.events;
import lsp.manager.event_bus;
import lsp.utils.text_coordinates;
extern "C" const TSLanguage* tree_sitter_tsf(void);
export namespace lsp::manager
{
class TreeSitter
{
public:
TreeSitter();
TreeSitter(const TreeSitter&) = delete;
TreeSitter& operator=(const TreeSitter&) = delete;
TreeSitter(TreeSitter&& other) noexcept;
~TreeSitter();
bool SetLanguage(const TSLanguage* language);
TSTree* Parse(const char* content, std::size_t length, TSTree* old_tree = nullptr);
TSParser* GetRawParser() const;
private:
TSParser* parser_;
};
class SyntaxTree
{
public:
explicit SyntaxTree(TSTree* tree);
~SyntaxTree();
void ApplyEdit(const protocol::TextDocumentContentChangeEvent& change, const protocol::string& content);
TSTree* Get() const;
TSNode GetRootNode() const;
private:
std::unique_ptr<TSTree, void (*)(TSTree*)> tree_;
};
class Parser
{
public:
explicit Parser(EventBus& event_bus);
~Parser();
TSTree* GetTree(const protocol::DocumentUri& uri) const;
TSParser* GetRawParser() const;
void Clear();
private:
void OnDocumentOpened(const events::DocumentOpened& event);
void OnDocumentChanged(const events::DocumentChanged& event);
void OnDocumentClosed(const events::DocumentClosed& event);
TreeSitter parser_;
std::unordered_map<protocol::DocumentUri, std::unique_ptr<SyntaxTree>> trees_;
EventBus& event_bus_;
mutable std::shared_mutex mutex_;
};
}
namespace lsp::manager
{
@@ -29,7 +95,7 @@ namespace lsp::manager
return ts_parser_set_language(parser_, language);
}
TSTree* TreeSitter::Parse(const char* content, size_t length, TSTree* old_tree)
TSTree* TreeSitter::Parse(const char* content, std::size_t length, TSTree* old_tree)
{
if (!parser_)
return nullptr;
-70
View File
@@ -1,70 +0,0 @@
#pragma once
#include <memory>
#include <optional>
#include <shared_mutex>
#include <unordered_map>
#include "./events.hpp"
#include "./event_bus.hpp"
#include "../protocol/protocol.hpp"
extern "C" {
#include <tree_sitter/api.h>
}
extern "C" const TSLanguage* tree_sitter_tsf(void);
namespace lsp::manager
{
class TreeSitter
{
public:
TreeSitter();
TreeSitter(const TreeSitter&) = delete;
TreeSitter& operator=(const TreeSitter&) = delete;
TreeSitter(TreeSitter&& other) noexcept;
~TreeSitter();
bool SetLanguage(const TSLanguage* language);
TSTree* Parse(const char* content, size_t length, TSTree* old_tree = nullptr);
TSParser* GetRawParser() const;
private:
TSParser* parser_;
};
class SyntaxTree
{
public:
explicit SyntaxTree(TSTree* tree);
~SyntaxTree();
void ApplyEdit(const protocol::TextDocumentContentChangeEvent& change, const protocol::string& content);
TSTree* Get() const;
TSNode GetRootNode() const;
private:
std::unique_ptr<TSTree, void (*)(TSTree*)> tree_;
};
class Parser
{
public:
explicit Parser(EventBus& event_bus);
~Parser();
TSTree* GetTree(const protocol::DocumentUri& uri) const;
TSParser* GetRawParser() const;
void Clear();
private:
void OnDocumentOpened(const events::DocumentOpened& event);
void OnDocumentChanged(const events::DocumentChanged& event);
void OnDocumentClosed(const events::DocumentClosed& event);
TreeSitter parser_;
std::unordered_map<protocol::DocumentUri, std::unique_ptr<SyntaxTree>> trees_;
EventBus& event_bus_;
mutable std::shared_mutex mutex_;
};
}
@@ -1,15 +1,88 @@
#include "symbol.hpp"
#include <spdlog/spdlog.h>
#include <chrono>
#include <filesystem>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <sstream>
#include <cctype>
#include "../utils/string.hpp"
#include "../language/ast/deserializer.hpp"
#include "../language/symbol/builder.hpp"
module;
export module lsp.manager.symbol;
import tree_sitter;
import spdlog;
import std;
import lsp.protocol;
import lsp.manager.event_bus;
import lsp.manager.events;
import lsp.language.ast;
import lsp.language.symbol;
import lsp.language.semantic;
import lsp.utils.string;
export namespace lsp::manager
{
class Symbol
{
public:
enum class SymbolSource
{
kEditing,
kWorkspace,
kSystem
};
struct IndexedSymbol
{
protocol::DocumentUri uri;
std::string name;
protocol::SymbolKind kind;
SymbolSource source;
language::symbol::SymbolId id;
};
explicit Symbol(EventBus& event_bus);
~Symbol();
void LoadSystemLibrary(const std::string& lib_path);
void LoadWorkspace(const protocol::DocumentUri& workspace_uri);
const language::symbol::SymbolTable* GetSymbolTable(const protocol::DocumentUri& uri) const;
const language::semantic::SemanticModel* GetSemanticModel(const protocol::DocumentUri& uri) const;
std::vector<const language::symbol::SymbolTable*> GetWorkspaceSymbolTables() const;
std::vector<const language::symbol::SymbolTable*> GetSystemSymbolTables() const;
std::vector<IndexedSymbol> QueryIndexedSymbols(protocol::SymbolKind kind, std::optional<SymbolSource> source = std::nullopt) const;
private:
void OnDocumentParsed(const events::DocumentParsed& event);
void OnDocumentReparsed(const events::DocumentReparsed& event);
void OnDocumentClosed(const events::DocumentClosed& event);
struct DocumentAnalysis
{
protocol::DocumentUri uri;
protocol::integer version;
std::unique_ptr<language::ast::Deserializer> deserializer;
std::unique_ptr<language::ast::Program> ast;
std::unique_ptr<language::symbol::SymbolTable> symbol_table;
std::unique_ptr<language::semantic::SemanticModel> semantic_model;
};
struct StoredSymbolEntry
{
std::unique_ptr<language::symbol::SymbolTable> symbol_table;
std::unique_ptr<language::semantic::SemanticModel> semantic_model;
};
void RebuildIndex();
void AddTableToIndex(const language::symbol::SymbolTable& table, const protocol::DocumentUri& uri, SymbolSource source);
bool IsTopLevelSymbol(const language::symbol::SymbolTable& table, language::symbol::SymbolId id) const;
std::unordered_map<std::string, StoredSymbolEntry> system_symbols_;
std::unordered_map<std::string, StoredSymbolEntry> workspace_symbols_;
std::unordered_map<protocol::DocumentUri, DocumentAnalysis> editing_symbols_;
std::unordered_map<std::string, std::vector<IndexedSymbol>, utils::IHasher, utils::IEqualTo> index_by_name_;
EventBus& event_bus_;
mutable std::shared_mutex mutex_;
};
}
namespace lsp::manager
{
@@ -68,7 +141,11 @@ namespace lsp::manager
if (!path.has_extension())
return false;
std::string ext = path.extension().string();
std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
std::transform(
ext.begin(),
ext.end(),
ext.begin(),
[](unsigned char ch) { return static_cast<char>(std::tolower(ch)); });
return ext == ".tsf" || ext == ".tsl";
}
@@ -510,7 +587,8 @@ namespace lsp::manager
.name = symbol.name(),
.kind = symbol.kind(),
.source = source,
.id = symbol.id() };
.id = symbol.id()
};
auto key = utils::ToLower(symbol.name());
index_by_name_[key].push_back(std::move(item));
-83
View File
@@ -1,83 +0,0 @@
#pragma once
#include <memory>
#include <unordered_map>
#include <shared_mutex>
#include <vector>
#include "../protocol/protocol.hpp"
#include "../language/symbol/table.hpp"
#include "../language/ast/deserializer.hpp"
#include "../language/semantic/semantic_model.hpp"
#include "./event_bus.hpp"
#include "./events.hpp"
#include "../utils/string.hpp"
namespace lsp::manager
{
class Symbol
{
public:
enum class SymbolSource
{
kEditing,
kWorkspace,
kSystem
};
struct IndexedSymbol
{
protocol::DocumentUri uri;
std::string name;
protocol::SymbolKind kind;
SymbolSource source;
language::symbol::SymbolId id;
};
explicit Symbol(EventBus& event_bus);
~Symbol();
void LoadSystemLibrary(const std::string& lib_path);
void LoadWorkspace(const protocol::DocumentUri& workspace_uri);
const language::symbol::SymbolTable* GetSymbolTable(const protocol::DocumentUri& uri) const;
const language::semantic::SemanticModel* GetSemanticModel(const protocol::DocumentUri& uri) const;
std::vector<const language::symbol::SymbolTable*> GetWorkspaceSymbolTables() const;
std::vector<const language::symbol::SymbolTable*> GetSystemSymbolTables() const;
std::vector<IndexedSymbol> QueryIndexedSymbols(protocol::SymbolKind kind, std::optional<SymbolSource> source = std::nullopt) const;
private:
void OnDocumentParsed(const events::DocumentParsed& event);
void OnDocumentReparsed(const events::DocumentReparsed& event);
void OnDocumentClosed(const events::DocumentClosed& event);
struct DocumentAnalysis
{
protocol::DocumentUri uri;
protocol::integer version;
std::unique_ptr<language::ast::Deserializer> deserializer;
std::unique_ptr<language::ast::Program> ast;
std::unique_ptr<language::symbol::SymbolTable> symbol_table;
std::unique_ptr<language::semantic::SemanticModel> semantic_model;
};
struct StoredSymbolEntry
{
std::unique_ptr<language::symbol::SymbolTable> symbol_table;
std::unique_ptr<language::semantic::SemanticModel> semantic_model;
};
void RebuildIndex();
void AddTableToIndex(const language::symbol::SymbolTable& table, const protocol::DocumentUri& uri, SymbolSource source);
bool IsTopLevelSymbol(const language::symbol::SymbolTable& table, language::symbol::SymbolId id) const;
std::unordered_map<std::string, StoredSymbolEntry> system_symbols_;
std::unordered_map<std::string, StoredSymbolEntry> workspace_symbols_;
std::unordered_map<protocol::DocumentUri, DocumentAnalysis> editing_symbols_;
std::unordered_map<std::string, std::vector<IndexedSymbol>, utils::IHasher, utils::IEqualTo> index_by_name_;
EventBus& event_bus_;
mutable std::shared_mutex mutex_;
};
}