Rust extractor: lossy structure and name-only call resolution (generic impls, traits, mods, use-lists, receivers)
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 18/100
Hướng nghiên cứu
Start in graphify/extract.py at extract_rust, plus _make_id, _file_stem and the label_to_nid lookup in extract(), and reproduce with the sample file in the issue. The author has a patch and 10 regression tests, so the work is mostly reviewing the design: scoped IDs, trait impls, receiver-based call resolution and cross-file resolution. Done means the sample's orphan nodes, merged IDs and name-only edges are gone, and the regression tests pass.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Version: graphifyy 0.7.0 (graphify/extract.py, extract_rust)
extract_rust loses most of the structure of idiomatic Rust. Reproduced with this file:
use std::fmt::{self, Display};
pub trait Reader { fn read(&self) -> u8; fn skip(&self) { helper(); } }
pub struct Foo<T> { x: T }
impl<T> Foo<T> { pub fn new(x: T) -> Self { Self { x } } pub fn go(&self) { Self::new(1); helper(); } }
impl Display for Foo<u8> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Ok(()) } }
impl Reader for Foo<u8> { fn read(&self) -> u8 { 0 } }
mod inner { pub fn helper() {} pub struct Foo; }
pub fn helper() { inner::helper(); println!("x"); }
pub type Alias = u8; pub const K: u8 = 1; macro_rules! m { () => {} }
Structure problems
- Generic impls create orphan nodes.
impl<T> Foo<T>/impl Foo<u8>produce nodesFoo<T>/Foo<u8>, separate from theFoostruct node. Methods hang off the orphans. - Trait is dropped from
impl Trait for Type. Noimplementsedge; trait impls look like inherent impls, and several impls of the same method name for one type (e.g. threeimpl From<_> for E) share one ID scheme. trait_itemreturns without descending. Trait methods produce no nodes, so calls from default method bodies (skip -> helper) are lost.- IDs ignore the inline
modpath, and are case-folded.inner::helperand top-levelhelperget the same ID, as doinner::FooandFoo; nodes merge andinner::helper()becomes a dropped self-call. Because_make_idlower-cases,const ITEMandfn item()also collide (first label wins). Across files,_file_stemisparent.stem, so everysrc/lib.rssharessrc.lib. - Missing node kinds:
mod,type,const,static,union,macro_rules!. usehandling is lossy:use std::fmt::{self, Display}yields one edge (the text before{), losingDisplay; nested/aliased lists are not flattened.
Call-resolution problems
The extractor resolves calls by bare name only (label_to_nid[name.lower()], last definition wins), ignoring qualifiers and receivers, so on a real workspace most edges for common names are wrong. Examples found by auditing the old output line by line:
Vec::new(),Cursor::new(..),HashMap::new(),u64::from(x),Default::default()are linked to any localfn new/fn from/fn default.v.len()/s.is_empty()/file.seek(..)on std types are linked to local methods with the same name.Value::Inline(..)/VrIndex(..)(enum variant / tuple-struct constructors) are linked to a function namedinline/ the type node.validator.enter_item(..)is linked to an unrelated freefn enter_item, not the method onvalidator's type.- Conversely, true calls are missed:
self.m()when several types in the file definem,Type::f()whenTypehas several impls, trait-qualified calls (Seek::seek(&mut s)), calls through generic bounds (V: Trait),if let Some(x) = x, loop/closure variables, and everything crossing a file boundary other than by unique name.
Patch
I have a patch (extract_rust replacement + a small Rust pass in extract() for cross-file resolution) and 10 regression tests. Happy to open a PR. Summary of the behaviour:
- IDs scoped by file path +
modpath and tagged by kind; generics stripped soimpl<T> Foo<T>attaches toFoo;implementsedges (also cross-file); trait methods as nodes; nodes for mod/type/const/static/macro; use-trees flattened. - Calls resolved with light receiver-type inference (parameters, typed/constructor
let, struct field types,Self, fn/method return types withResult/Option/Box/Arcunwrapped,if let Some(x), generic bounds,for/closure element types overVec/slice/array). When a call can reach several impls, an edge goes to each candidate withINFERREDconfidence. Calls on external types (Vec::new,u64::from, ...) and enum-variant/tuple-struct constructors produce no edge. Typed calls whose type lives in another file are resolved in a cross-file pass.
Measured on a real workspace
179 .rs files (a DICOM parser; calls counted over the whole graph, incl. cross-file), old extractor vs patched:
| old | patched | |
|---|---|---|
| nodes (in-file extraction) | 2658 | 5782+ |
calls edges |
3544 | 4607 (2482 EXTRACTED, 2125 INFERRED) |
The 134 old call edges that disappear were classified by source line: 68 Type::f() on external types, 43 enum-variant/tuple-struct constructors and chains on external types, 23 recv.f() on std types (len/is_empty/seek/read) — plus 4 validator.enter_* calls that used to point at the wrong free function and now point at the method. None was a Type::f() call on a type defined in the workspace.
Remaining limit
Where the type is only known to a real type checker (results of .map(..) / .collect(), macro-generated code), no edge is emitted rather than a guessed one.
- Ngôn ngữ chính
- Python
- Star
- 124k
- Fork
- 11.9k
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của Graphify-Labs/graphify
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
Graphify-Labs/graphify#3763 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Graphify-Labs/graphify#3611 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Nix supportĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
Graphify-Labs/graphify#3193 · 2 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 92/100
Graphify-Labs/graphify#2871 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Graphify-Labs/graphify#2865 ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của Graphify-Labs/graphify
Issue tương tự
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
aws-samples/sample-per-model-bedrock#261 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[UI/Accessibility] Low contrast text visibility in country selection dropdown on settings pageĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
pwncollege/dojo#1188 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug launcher packaging
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
tenstorrent/tt-studio#1426 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
python-attrs/cattrs#796 ·
Maintainer thường phản hồi trong vòng 1 ngày