## Summary - The `eventide` dep was renamed to [kotatsu](https://github.com/clice-io/kotatsu) with a broad rename of CMake identifiers, namespaces, header paths, and a few module reorgs (`serde` → `codec`, `reflection` → `meta`, `common` → `support`). Align clice to the new names. - CMake: FetchContent target, option prefix (`ETD_*` → `KOTA_*`, `ETD_SERDE_*` → `KOTA_CODEC_*`), target names (`eventide::{ipc::lsp,serde::toml,deco,zest}` → `kota::{ipc::lsp,codec::toml,deco,zest}`). - Namespaces: `eventide::` → `kota::`, `eventide::serde::` → `kota::codec::`, `eventide::refl::` → `kota::meta::`. The short `et` alias is dropped — all usages now spell `kota::` directly. - Headers: `eventide/*` → `kota/*`, including special cases `serde/serde/raw_value.h` → `codec/raw_value.h`, `ipc/json_codec.h` → `ipc/codec/json.h`, `common/meta.h` → `support/type_traits.h`, `common/ranges.h` → `support/ranges.h`. - Kotatsu split `JsonPeer` / `BincodePeer` out of `ipc/peer.h` into the codec-specific headers; added `kota/ipc/codec/{json,bincode}.h` includes where those types are used. - Depends on clice-io/kotatsu#110 (already merged) to prevent `-Wall -Wextra -Werror` from transitively propagating out of `kota::project_options`. ## Test plan - [x] `pixi run unit-test RelWithDebInfo` — 518/518 pass (9 skipped, unchanged from main) - [x] `pixi run integration-test RelWithDebInfo` — 119/119 pass - [x] `pixi run smoke-test RelWithDebInfo` — 2/2 pass - [x] `pixi run format` clean ## Notes - `tests/smoke/rapid_edit.jsonl` was intentionally left untouched: the embedded `#include "eventide/..."` strings are frozen snapshots of file contents the client sent at record time, not clice source. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated internal dependencies from `eventide` to `kota`, including async runtime, IPC transport, serialization codec, and metadata libraries. * Updated build configuration and CMake variables to align with the new dependency. * **Refactor** * Migrated internal implementation to use `kota` namespace and APIs throughout the codebase. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
437 lines
7.2 KiB
C++
437 lines
7.2 KiB
C++
#include <cstdint>
|
|
#include <vector>
|
|
|
|
#include "test/test.h"
|
|
#include "test/tester.h"
|
|
#include "feature/feature.h"
|
|
|
|
namespace clice::testing {
|
|
|
|
namespace {
|
|
|
|
namespace protocol = kota::ipc::protocol;
|
|
|
|
TEST_SUITE(FoldingRange, Tester) {
|
|
|
|
std::vector<protocol::FoldingRange> ranges;
|
|
|
|
enum class LegacyKind {
|
|
Namespace,
|
|
Class,
|
|
Enum,
|
|
Struct,
|
|
Union,
|
|
FunctionBody,
|
|
LambdaCapture,
|
|
FunctionParams,
|
|
FunctionCall,
|
|
Initializer,
|
|
AccessSpecifier,
|
|
Region,
|
|
};
|
|
|
|
void run(llvm::StringRef code) {
|
|
add_main("main.cpp", code);
|
|
ASSERT_TRUE(compile_with_pch());
|
|
ranges = feature::folding_ranges(*unit, feature::PositionEncoding::UTF8);
|
|
}
|
|
|
|
auto to_local_range(const protocol::FoldingRange& range) -> LocalSourceRange {
|
|
feature::PositionMapper converter(unit->interested_content(), feature::PositionEncoding::UTF8);
|
|
|
|
auto start = protocol::Position{
|
|
.line = range.start_line,
|
|
.character = range.start_character.value_or(0),
|
|
};
|
|
|
|
auto end = protocol::Position{
|
|
.line = range.end_line,
|
|
.character = range.end_character.value_or(0),
|
|
};
|
|
|
|
return LocalSourceRange(*converter.to_offset(start), *converter.to_offset(end));
|
|
}
|
|
|
|
void EXPECT_FOLDING(std::uint32_t index,
|
|
llvm::StringRef begin,
|
|
llvm::StringRef end,
|
|
LegacyKind,
|
|
std::source_location = std::source_location::current()) {
|
|
auto actual = to_local_range(ranges[index]);
|
|
auto begin_point = point(begin, "main.cpp");
|
|
auto end_point = point(end, "main.cpp");
|
|
|
|
ASSERT_EQ(actual.begin, begin_point);
|
|
ASSERT_EQ(actual.end, end_point);
|
|
}
|
|
|
|
using enum LegacyKind;
|
|
|
|
TEST_CASE(Namespace) {
|
|
run(R"cpp(
|
|
namespace single_line { }
|
|
|
|
namespace with_nodes $(1){
|
|
struct inner $(3){
|
|
int x;
|
|
}$(4);
|
|
}$(2)
|
|
|
|
namespace strange
|
|
$(5){
|
|
|
|
}$(6)
|
|
|
|
#define NS_BEGIN namespace ns {
|
|
#define NS_END }
|
|
|
|
$(7)NS_BEGIN
|
|
NS_END$(8)
|
|
)cpp");
|
|
|
|
ASSERT_EQ(ranges.size(), 4U);
|
|
EXPECT_FOLDING(0, "1", "2", Namespace);
|
|
EXPECT_FOLDING(1, "3", "4", Namespace);
|
|
EXPECT_FOLDING(2, "5", "6", Namespace);
|
|
EXPECT_FOLDING(3, "7", "8", Namespace);
|
|
}
|
|
|
|
TEST_CASE(Enum) {
|
|
run(R"cpp(
|
|
enum e1 $(1){
|
|
A,
|
|
B,
|
|
C
|
|
}$(2);
|
|
|
|
enum class e2 $(3){
|
|
A,
|
|
B,
|
|
C
|
|
}$(4);
|
|
|
|
enum e3 { D };
|
|
|
|
)cpp");
|
|
|
|
ASSERT_EQ(ranges.size(), 2U);
|
|
EXPECT_FOLDING(0, "1", "2", Enum);
|
|
EXPECT_FOLDING(1, "3", "4", Enum);
|
|
}
|
|
|
|
TEST_CASE(Record) {
|
|
run(R"cpp(
|
|
struct s1 $(1){
|
|
int x;
|
|
float y;
|
|
}$(2);
|
|
|
|
struct s2 {};
|
|
|
|
struct s3;
|
|
|
|
union u1 $(3){
|
|
int x;
|
|
float y;
|
|
}$(4);
|
|
|
|
struct u2 $(5){
|
|
struct s4 $(7){
|
|
|
|
}$(8);
|
|
}$(6);
|
|
|
|
void foo() $(9){
|
|
struct s5 $(11){
|
|
|
|
}$(12);
|
|
}$(10)
|
|
)cpp");
|
|
|
|
ASSERT_EQ(ranges.size(), 6U);
|
|
EXPECT_FOLDING(0, "1", "2", Struct);
|
|
EXPECT_FOLDING(1, "3", "4", Union);
|
|
EXPECT_FOLDING(2, "5", "6", Struct);
|
|
EXPECT_FOLDING(3, "7", "8", Struct);
|
|
EXPECT_FOLDING(4, "9", "10", FunctionBody);
|
|
EXPECT_FOLDING(5, "11", "12", Struct);
|
|
}
|
|
|
|
TEST_CASE(Method) {
|
|
run(R"cpp(
|
|
struct s2 $(1){
|
|
int x;
|
|
float y;
|
|
|
|
s2() = default;
|
|
}$(2);
|
|
|
|
struct s3;
|
|
|
|
struct s3 $(3){
|
|
void method() $(5){
|
|
int x = 0;
|
|
}$(6)
|
|
|
|
void parameter() $(7){
|
|
|
|
}$(8)
|
|
|
|
void skip() {};
|
|
}$(4);
|
|
)cpp");
|
|
|
|
ASSERT_EQ(ranges.size(), 4U);
|
|
EXPECT_FOLDING(0, "1", "2", Struct);
|
|
EXPECT_FOLDING(1, "3", "4", Struct);
|
|
EXPECT_FOLDING(2, "5", "6", FunctionBody);
|
|
EXPECT_FOLDING(3, "7", "8", FunctionBody);
|
|
}
|
|
|
|
TEST_CASE(Lambda) {
|
|
run(R"cpp(
|
|
auto z = $(1)[
|
|
x = 0, y = 1
|
|
]$(2) () $(3){
|
|
|
|
}$(4);
|
|
|
|
static int array[4];
|
|
|
|
auto s = $(5)[
|
|
x=0,
|
|
y = 1,
|
|
z = array[
|
|
0],
|
|
k = -1
|
|
]$(6) () $(7){
|
|
return;
|
|
}$(8);
|
|
|
|
auto l1 = [] () {};
|
|
|
|
auto l2 = [] () $(9){
|
|
|
|
}$(10);
|
|
|
|
auto l3 = [] () $(11){
|
|
return 0;
|
|
}$(12);
|
|
|
|
auto l4 = [] $(13)(
|
|
int x1,
|
|
int x2
|
|
)$(14) {};
|
|
)cpp");
|
|
|
|
ASSERT_EQ(ranges.size(), 7U);
|
|
EXPECT_FOLDING(0, "1", "2", LambdaCapture);
|
|
EXPECT_FOLDING(1, "3", "4", FunctionBody);
|
|
EXPECT_FOLDING(2, "5", "6", LambdaCapture);
|
|
EXPECT_FOLDING(3, "7", "8", FunctionBody);
|
|
EXPECT_FOLDING(4, "9", "10", FunctionBody);
|
|
EXPECT_FOLDING(5, "11", "12", FunctionBody);
|
|
EXPECT_FOLDING(6, "13", "14", FunctionBody);
|
|
}
|
|
|
|
TEST_CASE(Function) {
|
|
run(R"cpp(
|
|
void e() {};
|
|
|
|
void f $(1)(
|
|
|
|
|
|
)$(2) $(3){
|
|
|
|
}$(4)
|
|
|
|
void g $(5)(
|
|
int x,
|
|
int y = 2
|
|
)$(6) $(7){
|
|
int z;
|
|
}$(8)
|
|
|
|
void h() $(9){
|
|
int x = 0;
|
|
}$(10)
|
|
|
|
void i( ) { };
|
|
|
|
void j $(11)(
|
|
int p1,
|
|
int p2,
|
|
...
|
|
)$(12);
|
|
|
|
void k() $(13){
|
|
|
|
}$(14)
|
|
)cpp");
|
|
|
|
ASSERT_EQ(ranges.size(), 7U);
|
|
EXPECT_FOLDING(0, "1", "2", FunctionParams);
|
|
EXPECT_FOLDING(1, "3", "4", FunctionBody);
|
|
EXPECT_FOLDING(2, "5", "6", FunctionParams);
|
|
EXPECT_FOLDING(3, "7", "8", FunctionBody);
|
|
EXPECT_FOLDING(4, "9", "10", FunctionBody);
|
|
EXPECT_FOLDING(5, "11", "12", FunctionParams);
|
|
EXPECT_FOLDING(6, "13", "14", FunctionBody);
|
|
}
|
|
|
|
TEST_CASE(FunctionCall) {
|
|
run(R"cpp(
|
|
int f(int p1, int p2, int p3, int p4, int p5, int p6) { return p1 + p2; }
|
|
|
|
int main() $(1){
|
|
int x = f(1, 2, 3, 4, 5, 6);
|
|
|
|
int y = f $(2)(
|
|
1, 2, 3,
|
|
4, 5, 6
|
|
)$(3);
|
|
|
|
return f $(4)(
|
|
1, 2, 3,
|
|
4, 5, 6
|
|
)$(5);
|
|
}$(6)
|
|
)cpp");
|
|
|
|
ASSERT_EQ(ranges.size(), 3U);
|
|
EXPECT_FOLDING(0, "1", "6", FunctionBody);
|
|
EXPECT_FOLDING(1, "2", "3", FunctionCall);
|
|
EXPECT_FOLDING(2, "4", "5", FunctionCall);
|
|
}
|
|
|
|
TEST_CASE(CompoundStmt) {
|
|
run(R"cpp(
|
|
int main() $(1){
|
|
|
|
$(3){
|
|
$(5){
|
|
//
|
|
}$(6)
|
|
|
|
$(7){
|
|
//
|
|
}$(8)
|
|
|
|
//
|
|
}$(4)
|
|
|
|
return 0;
|
|
}$(2)
|
|
|
|
)cpp");
|
|
}
|
|
|
|
TEST_CASE(InitializeList) {
|
|
run(R"cpp(
|
|
struct L { int xs[4]; };
|
|
|
|
L l1 = $(1){
|
|
1, 2, 3, 4
|
|
}$(2);
|
|
|
|
L l2 = $(3){
|
|
//
|
|
//
|
|
}$(4);
|
|
|
|
)cpp");
|
|
|
|
ASSERT_EQ(ranges.size(), 2U);
|
|
EXPECT_FOLDING(0, "1", "2", Initializer);
|
|
EXPECT_FOLDING(1, "3", "4", Initializer);
|
|
}
|
|
|
|
TEST_CASE(AccessSpecifier) {
|
|
run(R"cpp(
|
|
class c1 $(1){
|
|
public$(3):
|
|
private$(4):
|
|
protected$(5):
|
|
}$(2);
|
|
|
|
class c2 $(6){
|
|
public$(8):
|
|
int x;
|
|
|
|
private$(9):
|
|
float y;
|
|
|
|
protected$(10):
|
|
double z;
|
|
}$(7);
|
|
|
|
#define PUBLIC public:
|
|
#define PRIVATE private:
|
|
#define PROTECTED protected:
|
|
|
|
class c3 $(11){
|
|
$(13)PUBLIC
|
|
int a;
|
|
$(15)PRIVATE$(14)
|
|
int b;
|
|
$(17)PROTECTED$(16)
|
|
int c;
|
|
}$(12);
|
|
)cpp");
|
|
|
|
EXPECT_FOLDING(0, "1", "2", Class);
|
|
EXPECT_FOLDING(1, "3", "4", AccessSpecifier);
|
|
EXPECT_FOLDING(2, "4", "5", AccessSpecifier);
|
|
EXPECT_FOLDING(3, "5", "2", AccessSpecifier);
|
|
|
|
EXPECT_FOLDING(4, "6", "7", Class);
|
|
EXPECT_FOLDING(5, "8", "9", AccessSpecifier);
|
|
EXPECT_FOLDING(6, "9", "10", AccessSpecifier);
|
|
EXPECT_FOLDING(7, "10", "7", AccessSpecifier);
|
|
|
|
EXPECT_FOLDING(8, "11", "12", Class);
|
|
EXPECT_FOLDING(9, "13", "14", AccessSpecifier);
|
|
EXPECT_FOLDING(10, "15", "16", AccessSpecifier);
|
|
EXPECT_FOLDING(11, "17", "12", AccessSpecifier);
|
|
}
|
|
|
|
TEST_CASE(Directive) {
|
|
run(R"cpp(
|
|
#ifdef M1
|
|
|
|
#else
|
|
|
|
#ifdef M2
|
|
|
|
|
|
#endif
|
|
|
|
#endif
|
|
)cpp");
|
|
}
|
|
|
|
TEST_CASE(PragmaRegion) {
|
|
run(R"cpp(
|
|
$(1)#pragma region level1
|
|
$(2)#pragma region level2
|
|
$(3)#pragma region level3
|
|
|
|
#$(4)pragma endregion level3
|
|
|
|
|
|
#$(5)pragma endregion level2
|
|
|
|
|
|
#$(6)pragma endregion level1
|
|
|
|
#pragma endregion // mismatch region, skipped
|
|
#pragma region // mismatch region, skipped
|
|
)cpp");
|
|
}
|
|
|
|
}; // TEST_SUITE(FoldingRange)
|
|
|
|
} // namespace
|
|
|
|
} // namespace clice::testing
|