From f3e865661784f9d96b6cdb25a22da9629bb3105b Mon Sep 17 00:00:00 2001 From: coseto6125 <80243681+coseto6125@users.noreply.github.com> Date: Fri, 22 May 2026 02:48:19 +0800 Subject: [PATCH] fix(workspace): unbreak main after #285/#291/#292 merge collision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three recent PRs landed on main with overlapping schema changes but were not rebased against each other, leaving main in a state that fails to compile (CI red on 162c52db): - #285 (T1-4 + T1-5 + T1-11) — `Node.uid: StrRef → u64`, added `Node.owner_class: StrRef`, made `uid::compute` the canonical UID source. - #291 (T4-7 SchemaField + MirrorsField) — added `post_process/schema_field_mirrors.rs`, switched `RawSchemaField.{name, owner_class}` from `StrRef` to `Box`. - #292 (T7-2 per-symbol content_hash) — added `Node.content_hash: u64`. The five resulting compile errors are mechanical: each call site needs to be brought to the shape the PR author would have written if they had rebased against the other two. This commit applies that reconciliation without rewriting history (no force-push to main). - `post_process/schema_field_mirrors.rs:99-118` — replace the `format!()` + `string_pool.add()` UID construction with `uid::compute(NodeKind::SchemaField, &path_str, Some(owner_name), field_name)`, the T1-5 canonical pattern. Adds the now-required `content_hash: 0` (synthetic mirror node, no source span — per T7-2 doc convention) and `owner_class: string_pool.add(owner_name)` (T1-11 rename isolation key: a SchemaField like `Foo.id` correctly belongs to class `Foo`). Side effect: drops one heap allocation per mirror node (no more `format!()` String + pool.add round-trip). - `protobuf/parser.rs:101-110` — replace `pool.add(&field_name)` and `pool.add(owner)` (StrRef-returning) with `field_name.into_boxed_str()` and `Box::from(owner.as_str())`. Drops the now-unused `pool: &mut StringPool` parameter from `extract_proto_fields` plus the `StringPool` allocation at the call site (3 cosmetic edits in one file). - `python/parser.rs` — add `use ecp_core::pool::StringPool;` import that the existing T5-2 event-topic wire-up at line 1094 already assumed. Verified: `cargo check --workspace --all-targets --all-features`, `cargo clippy --workspace --all-targets --all-features -- -D warnings`, and `cargo test --workspace --no-fail-fast` (2805 passed, 15 ignored) all clean. --- .../src/post_process/schema_field_mirrors.rs | 22 ++++++++++++------- crates/ecp-analyzer/src/protobuf/parser.rs | 10 ++++----- crates/ecp-analyzer/src/python/parser.rs | 1 + 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/crates/ecp-analyzer/src/post_process/schema_field_mirrors.rs b/crates/ecp-analyzer/src/post_process/schema_field_mirrors.rs index b9e015b56..7a0f0576e 100644 --- a/crates/ecp-analyzer/src/post_process/schema_field_mirrors.rs +++ b/crates/ecp-analyzer/src/post_process/schema_field_mirrors.rs @@ -40,6 +40,7 @@ use crate::resolution::index::SymbolTable; use ecp_core::analyzer::types::{LocalGraph, SchemaType}; use ecp_core::graph::{Edge, Node, NodeKind, RelType}; use ecp_core::pool::StringPool; +use ecp_core::uid; use rustc_hash::FxHashMap; /// Promote `RawSchemaField`s to `SchemaField` Nodes + emit `HasProperty` @@ -96,23 +97,28 @@ pub fn emit_edges( continue; }; - // UID format: stable across reindex; includes framework so - // cross-framework mirrors with same (owner, name) get distinct - // UIDs. Format mirrors File-node UID convention. - let uid_str = format!( - "SchemaField:{:?}:{}.{}:{}", - raw_sf.framework, owner_name, field_name, path_str + // UID: T1-5 canonical xxh3-64 over (kind, path, owner, name). + // owner_class is included so cross-framework mirrors with the same + // (owner, name) but different SchemaField nodes get distinct UIDs + // via path / owner disambiguation upstream. + let node_uid = uid::compute( + NodeKind::SchemaField, + &path_str, + Some(owner_name), + field_name, ); - let uid_ref = string_pool.add(&uid_str); let name_ref = string_pool.add(field_name); + let owner_ref = string_pool.add(owner_name); let sf_idx = nodes.len() as u32; nodes.push(Node { - uid: uid_ref, + uid: node_uid, name: name_ref, file_idx, kind: NodeKind::SchemaField, span: raw_sf.span, community_id: 0, + owner_class: owner_ref, + content_hash: 0, }); // HasProperty: -> . Non-heuristic diff --git a/crates/ecp-analyzer/src/protobuf/parser.rs b/crates/ecp-analyzer/src/protobuf/parser.rs index 502bc5afe..6bc6fe3e9 100644 --- a/crates/ecp-analyzer/src/protobuf/parser.rs +++ b/crates/ecp-analyzer/src/protobuf/parser.rs @@ -8,7 +8,6 @@ use super::schema_extractors::{ }; use ecp_core::analyzer::provider::LanguageProvider; use ecp_core::analyzer::types::{LocalGraph, RawSchemaField}; -use ecp_core::pool::StringPool; use std::path::Path; pub struct ProtobufProvider; @@ -28,8 +27,7 @@ impl LanguageProvider for ProtobufProvider { let text = std::str::from_utf8(source) .map_err(|e| anyhow::anyhow!("protobuf: UTF-8 decode error in {:?}: {}", path, e))?; - let mut pool = StringPool::new(); - let fields = extract_proto_fields(text, &mut pool); + let fields = extract_proto_fields(text); let schema_fields = (!fields.is_empty()).then(|| fields.into_boxed_slice()); Ok(LocalGraph { @@ -48,7 +46,7 @@ impl LanguageProvider for ProtobufProvider { /// - `depth`: brace nesting depth. A top-level `message` bumps depth to 1; /// any nested `{` (including nested messages, oneofs, options) bumps it /// further. Fields are only emitted when `depth == 1`. -fn extract_proto_fields(text: &str, pool: &mut StringPool) -> Vec { +fn extract_proto_fields(text: &str) -> Vec { let mut out: Vec = Vec::new(); let mut current_message: Option = None; let mut depth: u32 = 0; @@ -102,9 +100,9 @@ fn extract_proto_fields(text: &str, pool: &mut StringPool) -> Vec