Repository navigation
fix(network): Scala/Rust brace selectors, Kotlin declarations, Dart package:, shell variable paths - #3607
Merged
Conversation
…ackage:, shell variable paths (#3595 #3596 #3597 #3598) - #3595: `a.b.{C, D => E}` / `a::{b, c::{d}}` distribute their prefix to every selector (galaxyscope._expand_import_selectors). The old reading deleted the braces and split on commas: `a.b. C` and a bare `D`, which never resolved -- or, bare, linked across languages (syn's `use crate::ty::{ReturnType, Type}` -> zig's Type.zig). Only a brace right after `.`/`::`/`\` is a group; `${VAR}` and `{{ x }}` keep the old split. Scala also resolves by declared name, object members, and package objects (`io.circe.syntax._` -> syntax/package.scala). Rust `crate::`/`self::`/`super::` paths never reach the typosquat radar. - #3596: Kotlin `a.b.Util.X` is Util's file (member retry, now only onto a capitalized owner -- `java.util.X` is never a lone util.kt), and `a.b.asName` is the one file under .../a/b/ declaring it (a test's helper of the same name is not what production code imports). - #3597: Dart `package:name/path.dart` is the path tail name/lib/path.dart; `dart:` is the SDK; relative URIs resolve beside the importer. - #3598: shell `source "$VAR/x/y.sh"` resolves only by its literal tail (a bare name beside the importer); `~/...` is never the repository. import_graph_accuracy (precision / recall): kotlin 100/62.1 -> 99.1/95.2, dart 99.1/80.8 -> 99.1/95.3, scala 99.4/33.0 -> 98.2/54.5, shell 87.5/75.0 -> 100/100, rust 94.7/100 -> 100/100; the other 15 unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YAtpBfGGyBGGovitSVaM5Q
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #3595. Fixes #3596. Fixes #3597. Fixes #3598.
These four import-graph bugs were found by the 20-language accuracy check (#3594).
#3595: brace selectors (Scala, Rust).
galaxyscope.extract_raw_importsdeleted the braces and then split on commas. Soimport io.circe.{ Decoder, Json }becameio.circe. Decoderplus a bareJson: one never resolved, and the other linked across languages by name. For example, syn'suse crate::ty::{ReturnType, Type};linked Rust to Zig'sType.zig. New_expand_import_selectorsdistributes the prefix to every selector:=>/asrenames,_wildcards;selfselector names the prefix itself.Only a
{right after.,::or\counts as a group.${VAR}(shell) and{{ x }}(HTML templates) keep the old comma split exactly.Scala also gets:
Error.scaladeclaresDecodingFailure), plus object members;io.circe.syntax._resolves tosyntax/package.scala;Rust
crate::/self::/super::paths name this crate, so they never reach the typosquat radar. Without that, the full paths produced a new false alert: bevy'scrate::component::Components"mimics"Component.#3596: Kotlin.
a.b.Util.X(an object member or nested class) isUtil's file. The member retry now only lands on a capitalized owner, sojava.util.Collectionsnever becomes a loneutil.kt.a.b.asName(a top-level function or property) is the one file under…/a/b/that declares it, found from the functions and classes the scan already extracts.#3597: Dart.
package:name/path.dartis the path tailname/lib/path.dart;dart:is the SDK; relative URIs resolve beside the importer.#3598: shell.
source "$VAR/x/y.sh"resolves only by its literal tail after the last expansion. A bare name resolves beside the importer. The stem alone never decides:$rvm_path/scripts/completionis no longerlib/completion.bash, and$XDG_CONFIG_HOME:-$HOME/.configis no longer aconfig.yml.~/...is never the repository.Measured:
import_graph_accuracy.py(precision / recall)Baseline regenerated. The small precision dips were checked against source:
kotlin("Example.kt", """ import … """).build.sbtstring (import io.circe._).Both are the capture-reads-comments-and-strings class (#3600). The engine resolves the captured token correctly:
io.circe._really is thecircepackage object.Remaining Scala misses: 381 of 458 import something with no single file.
io.circe.benchmark._covers ten files.scala-2/andscala-3/both definesemiauto, so the name is ambiguous (Dependency Attribution Error duplicate filenames #261).Remaining Kotlin misses: Kotlin function extraction drops extension functions with a generic receiver (filed separately).
Type of change
CI checklist
python -m pytest tests/: 11,150 passed.crucible_check.py --update --yes: both fixtures reblessed. Scope is below.import_graph_accuracy.py --ci: OK, 20 languages.Golden-master scope
Zero-dependency fixture: 155 differences, 39 of them coordinate or composition-fit ripple.
Extracted Dependenciesbecomes full selector paths, with the edges and exposures that follow.zig/zig/Type.ziglost syn'suse crate::ty::{ReturnType, Type}.firewall.imports_unknown11179 → 11162.typosquat_hitsis unchanged at 27, and no Alert changes.The PHP and HTML dependency lists are untouched. An earlier iteration re-split PHP's existing multi-line capture garbage and cut an HTML
{{ placeholder }}/path. The selector guard above prevents both, and the PHP capture bug itself is filed separately.Verification
🤖 Generated with Claude Code
https://claude.ai/code/session_01YAtpBfGGyBGGovitSVaM5Q
Generated by Claude Code