You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> **Phạm vi Task A1**: vẫn thuần string-manipulation (chỉ thêm bước strip visibility) — **không**
296
+
> chuyển sang AST-based traversal của `use_declaration` như `docs/rust-support-research.md` §R0.1
297
+
> mô tả ("parse bằng cấu trúc node tree-sitter... sửa luôn nested groups"). Nested groups như
298
+
> `use a::{b::{c, d}, e}` vẫn chưa được xử lý đúng sau task này — không phải regression (đã sai
299
+
> y hệt trước đó), chỉ là scope Task A1 hẹp hơn cách research doc mô tả. Không chặn merge, chỉ
300
+
> ghi rõ để không ai tưởng nested groups đã được sửa xong.
301
+
293
302
-[ ]**Step 4: Chạy — xác nhận PASS**`cargo test -p ci-core --lib imports::tests` và `cargo test -p ci-core --test rust_indexing pub_use_reexport_is_indexed` → expected: cả hai PASS
Thay đường strip-prefix sai trong `resolve_module_to_path` bằng resolver Rust dùng `CrateMap`.
499
+
500
+
> **Lưu ý số dòng**: các trích dẫn `pipeline.rs:NNN` dưới đây đã cập nhật theo commit
501
+
> `9d45c63` ("prefer same-file candidate when resolving a call by bare name", đã merge trước
502
+
> khi plan này được viết ra nhưng phần phân tích ban đầu không tính tới), commit này chèn thêm
503
+
> ~21 dòng vào giữa file (khối "same-file preference" trong `rebuild_graph`, dòng ~440-472).
504
+
> Khối đó nằm **trước** và **tách biệt** với `resolve_import_targets`/`resolve_module_to_path`
505
+
> mà Task A3 sửa — không có tương tác chức năng, chỉ cần biết để số dòng khớp bản hiện tại.
490
506
Đây là task đóng gap #2 (cross-crate `to_path = NULL`). Scope Tier-0: `crate::`, tên crate
491
507
ngoài, `self::` resolve chính xác; `super::` chấp nhận xấp xỉ (climb theo thư mục) và ghi chú
492
508
rõ — phần dư để Phase B phủ.
@@ -615,7 +631,7 @@ fn resolve_rust_module(
615
631
}
616
632
```
617
633
618
-
-[ ]**Step 4: Rẽ nhánh rust trong `resolve_module_to_path`** — sửa đầu hàm (pipeline.rs:526, ngay sau khối `let m = ...; if m.is_empty()`), thêm tham số `crate_map` và ưu tiên resolver rust cho file `.rs`. Đổi signature:
634
+
-[ ]**Step 4: Rẽ nhánh rust trong `resolve_module_to_path`** — sửa đầu hàm (pipeline.rs:547, ngay sau khối `let m = ...; if m.is_empty()`), thêm tham số `crate_map` và ưu tiên resolver rust cho file `.rs`. Đổi signature:
619
635
```rust
620
636
fnresolve_module_to_path(
621
637
from_path:&str,
@@ -638,7 +654,7 @@ fn resolve_module_to_path(
638
654
// ... existing generic body unchanged from here ...
639
655
```
640
656
641
-
-[ ]**Step 5: Build & truyền `CrateMap` trong `resolve_import_targets`** — sửa hàm (pipeline.rs:489). Nó cần `project_root` để build map; hiện chỉ nhận `tx`. Thêm tham số. Sửa signature + thân:
657
+
-[ ]**Step 5: Build & truyền `CrateMap` trong `resolve_import_targets`** — sửa hàm (pipeline.rs:510). Nó cần `project_root` để build map; hiện chỉ nhận `tx`. Thêm tham số. Sửa signature + thân:
642
658
```rust
643
659
fnresolve_import_targets(
644
660
tx:&rusqlite::Transaction,
@@ -653,7 +669,7 @@ fn resolve_import_targets(
653
669
}
654
670
```
655
671
656
-
Và tại call site trong `rebuild_graph` (pipeline.rs:480), đổi `resolve_import_targets(tx)?;` thành nhận map. `rebuild_graph` cũng chưa có `project_root` — thêm tham số vào nó và truyền từ 2 call site (`run_indexing_pipeline`~712, incremental ~823). Chuỗi thay đổi:
672
+
Và tại call site trong `rebuild_graph` (pipeline.rs:501), đổi `resolve_import_targets(tx)?;` thành nhận map. `rebuild_graph` cũng chưa có `project_root` — thêm tham số vào nó và truyền từ 2 call site (`run_indexing_pipeline`~733, incremental ~844). Chuỗi thay đổi:
> **Lưu ý:** thêm `trait_item` vào `class_node_types` để method bên trong trait nhận
730
-
> `class_context` = tên trait (`class_name_field = "type"` — với `trait_item` field tên là
731
-
> `name`, không phải `type`; kiểm tra: nếu `trait_item` dùng field `name`, cần xử lý riêng).
732
-
> **Executor phải verify**: chạy Step 4; nếu `Runner::run` ra qualified_name sai (thiếu tên
733
-
> trait), thì `class_name_field` cho trait khác impl — khi đó tách logic tên-class theo node
734
-
> kind trong `walk_symbols` (impl→field `type`, trait→field `name`). Test ở Step 1 là oracle.
735
747
736
-
-[ ]**Step 4: Chạy — xác nhận PASS**`cargo test -p ci-core --test rust_indexing` và full `cargo test -p ci-core` → expected: PASS, không regression (đặc biệt các test symbol Rust có sẵn trong `parser.rs`/`pipeline.rs`).
-[ ]**Step 5: Chạy — xác nhận PASS**`cargo test -p ci-core --test rust_indexing` và full `cargo test -p ci-core` → expected: PASS, không regression (đặc biệt các test symbol Rust có sẵn trong `parser.rs`/`pipeline.rs`).
-[ ]**Step 2: Chạy — xác nhận FAIL**`cargo test -p ci-core --test rust_indexing constructor_binding_infers_receiver_type` → expected: FAIL (textual, edge có thể không tồn tại theo target_class)
776
-
-[ ]**Step 3: Thêm inference** — trong `extract_type_map_impl` (parser.rs, hàm chứa vòng `while let Some(node) = stack.pop()`~810), thêm một nhánh rust: khi gặp `let_declaration` không có field `type` nhưng có `value` là constructor. Chèn ngay sau khối `if binding_kinds.contains(...)`:
820
+
-[ ]**Step 3: Thêm inference** — trong `extract_type_map_from_tree` (parser.rs, hàm chứa vòng `while let Some(node) = stack.pop()`~810), thêm một nhánh rust: khi gặp `let_declaration` không có field `type` nhưng có `value` là constructor. Chèn ngay sau khối `if binding_kinds.contains(...)`:
777
821
```rust
778
822
// Rust constructor inference: `let x = Foo::new(...)`, `Foo::default()`,
779
823
// or `Foo { .. }` binds x to type Foo even without a type annotation.
> `scip-overlay`: `tempfile = { version = "3", optional = true }` và thêm vào
1417
1461
> `scip-overlay = ["dep:scip", "dep:tempfile"]`; giữ dòng dev-dependency cho test khác).
1418
1462
1419
-
-[ ]**Step 4: Wire vào server** — trong `crates/ci-server/src/lib.rs`, sau khi indexer đặt `phase=Ready` trong `spawn_blocking` (sau block 70-97), thêm (feature-gated):
1463
+
-[ ]**Step 4: Wire vào server** — trong `crates/ci-server/src/lib.rs`, sau khi indexer đặt `phase=Ready` trong `spawn_blocking` (khối hiện tại là dòng 53-113; điểm chèn đúng là ngay sau khối `if index_ok { ... }` ở dòng 99-105, cạnh lệnh `bootstrap_embeddings(&conn, ...)` đã có sẵn ở dòng 107-109, trước khi gọi `watcher::run_watch_loop` ở dòng 112), thêm (feature-gated):
-[ ]**Step 1: Viết harness**`benchmarks/b2_call_graph_quality/run_benchmark.py` — pseudo-flow (executor hoàn thiện theo `benchmarks/lib/mcp_client.py` sẵn có, cùng cách b3/b4/b6 đã dùng):
1456
1509
1. Nhận `--repo <path>` (mặc định: chính `ci`).
1457
1510
2. Chạy `rust-analyzer scip <repo> --output oracle.scip`; decode bằng `scip print --json` (hoặc crate) → tập cạnh `(caller_file:line → callee_def_file:line)` cho các ref không-local.
1458
1511
3. Chạy `ci index <repo>`; đọc `.codeindex/index.db``call_edges` (Rust) → tập cạnh tương ứng qua `symbols.line_start`.
1459
1512
4. Tính precision = |ci ∩ oracle| / |ci|, recall = |ci ∩ oracle| / |oracle|, phân tách theo `edge_confidence`.
1460
1513
5. In bảng; ghi JSON để track qua thời gian.
1461
-
-[ ]**Step 2: Chạy baseline**`python benchmarks/rust_precision/run.py --repo .` → ghi lại số precision/recall hiện tại (sau Phase A). Đây là mốc để mọi thay đổi Rust về sau đối chiếu.
-[ ]**Step 2: Chạy baseline**`python benchmarks/b2_call_graph_quality/run_benchmark.py --repo .` → ghi lại số precision/recall hiện tại (sau Phase A). Đây là mốc để mọi thay đổi Rust về sau đối chiếu.
1515
+
-[ ]**Step 3: Cập nhật `benchmarks/README.md`** — đổi dòng B2 sang `Implemented` kèm link tới `b2_call_graph_quality/`.
0 commit comments