Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Elixir: every alias/import edge is dropped at build — definition ids carry a file-stem prefix, reference ids do not

Đang mở
#3,565 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

  • #3566 của @pavanetti — đã đóng, không merge

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
35/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
elixir, python
Lĩnh vực
devtools

Hướng nghiên cứu

Start in elixir.py around the definition and alias/import target ID generation, then trace build_from_json and compare the existing _resolve_kotlin_import_targets path. Reproduce with the supplied graphify update example and inspect graph.json. Done means valid Elixir module dependency edges survive the build while unresolved external modules remain dangling.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Version: 0.9.61 (fe66389) · macOS · Python 3.14

Summary

extract_elixir mints a module definition id as _make_id(file_stem, module_name) but mints the target of an alias/import/require/use edge as _make_id(module_name), with no stem. The two can never be equal, so build_from_json's node-set prune drops the edge and Elixir's entire module-dependency layer disappears from the graph.

The failure is silent in the way that matters: extraction reports no error, both endpoints exist as nodes, the file parses, the node count looks right. Only the edge is missing. A module aliased by a dozen callers reports degree 2, and community detection degenerates to roughly one community per file.

extract_elixir already assumes something downstream will reconcile this — its own dangling-edge filter deliberately exempts relation == "imports" so these edges survive the extractor. Nothing downstream ever resolves them.

Reproduction

mkdir -p repro/lib/my_app
cat > repro/lib/my_app/repo.ex <<'EOF'
defmodule MyApp.Repo do
  def insert(x), do: x
end
EOF
cat > repro/lib/my_app/user.ex <<'EOF'
defmodule MyApp.User do
  alias MyApp.Repo
  def save(x), do: Repo.insert(x)
end
EOF
graphify update repro
python -c "
import json, collections
g = json.load(open('repro/graphify-out/graph.json'))
print(collections.Counter(e['relation'] for e in g['links']))"

No imports edge reaches graph.json. The extractor emitted one.

The two conflicting ids

lib/my_app/repo.ex              NODE  lib_my_app_repo_myapp_repo   label 'MyApp.Repo'   # elixir.py:119
lib/my_app/user.ex  alias ...   EDGE  imports -> myapp_repo                             # elixir.py:167

lib_my_app_repo_myapp_repo != myapp_repo.

Measured impact

A 980-file Phoenix/Ecto application (lib/ only), graphify 0.9.61:

before after fix
imports edges emitted 4,292 4,292
surviving the build 0 (0.0%) 3,531 (82.3%)
cross-file edge share 8.1% 27.4%
Louvain communities / single-file 562 / 445 113 / 49

Whole repo (2,470 .ex/.exs): 8,570 emitted, 0 surviving → 6,390 (74.6%). The residual unresolved are genuine externals (Logger, Ecto.Query, deps) with no node in the corpus, which correctly stay dangling.

Source contains 2,805 real alias/import statements; graph.json contained 28 imports edges.

Why the per-file extractor cannot fix it

An Elixir alias names a BEAM module, not a path, so extract_elixir — which sees one file at a time — cannot know which file defines it. Guessing a path from Macro.underscore conventions breaks on umbrella apps, :elixirc_paths, acronym modules (HTTPClient → http_client), and multi-module files. So the target_file approach from #2195 (which resolves path-valued specifiers on disk) does not apply here.

This is the same shape as Kotlin #2526, whose own docstring describes the identical symptom: "That target dangles (node ids carry a file-stem prefix), so build pruned every Kotlin import."

Note: no cross-module call edges either

Independent of this bug, extract_elixir emits no cross-module call edge in any style — Bar.run(x) after alias, and fully-qualified MyApp.Foo.Bar.run(x), both produce nothing. Fixing the ids therefore restores the module dependency layer, not a call graph. Worth stating so the improvement is not over-read.

The same asymmetry exists in other extractors

While confirming the above, the pattern definition = _make_id(stem, name) / reference = _make_id(name) was reproduced with 0 surviving cross-file edges in: Rust (use), Fortran, Julia, Apex, Verilog, Razor, Blade, Dart, Scala, Groovy, Zig, and Pascal (different root cause, same symptom). Partial loss in Go, PowerShell, Ruby, OCaml.

Two failure modes: dangling (target matches nothing, pruned) and sourced ghost (the reference site calls add_node, minting a duplicate stub attributed to the referencing file). Python, TS/JS, Svelte/Vue/Astro, PHP, C, C++, Obj-C, C#, Kotlin, Swift, Lua, SQL, Common Lisp, Bash verified OK.

Happy to split that into a separate tracking issue — flagging it here only because the Elixir fix is one instance of it.

Proposed fix

PR to follow: stamp the written module name as metadata.target_fqn and repoint the edge in a corpus-wide resolver, guarded on a single candidate so nothing is fabricated — mirroring _resolve_kotlin_import_targets. Definition ids are left untouched, so existing graphs keep their node ids.

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

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. 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.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của Graphify-Labs/graphify

Tất cả issue của Graphify-Labs/graphify

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.