Skip to content

Scala: parse import selectors/aliases/wildcards and resolve imports against the declared package instead of the directory layout #2153

Open

Description

@htarnacki

What problem does this solve?

Scala files are parsed with the generic import fallback, which loses most of what a Scala import says, and the package clause is not recorded at all:

  • selector groups import a.b.{C, D} become one opaque import,
  • aliases import a.b.{C => Alias} are not bound, so Alias.method() never resolves,
  • wildcards import a.b._ are ignored,
  • the file's namespace is derived from the physical directory, but Scala projects routinely declare package com.example.app.account in files that do not live under com/example/app/account/.

As a result IMPORTS edges are guessed from the directory layout and cross-package CALLS edges for aliased or selector-imported objects are missing or bound to the wrong same-named object.

Version: built from source, main @ 9b24332 (v0.10.8-181), Linux x64.

Dummy snippet:

package com.example.app.account
import com.example.app.model.{Target, Helper => H}
import com.example.app.util._

object AccountService {
  def run(): Unit = { H.assist(); Target.make() }
}

Expected: namespace = com.example.app.account, one CBMImport per selector (Target, H → com.example.app.model.Helper, wildcard com.example.app.util._), and H.assist() resolving to com.example.app.model.Helper.assist via the import_map strategy.

Proposed solution

  1. Parse Scala import statements into one CBMImport per selector; keep the alias as the local name and the full path as the target; record wildcards.
  2. Record the package clause as the file namespace (namespace_name).
  3. Thread the file language through import resolution so Scala imports resolve against declared packages first and fall back to the directory-based lookup only when no package matches (pass_pkgmap, pass_imports).

No behaviour change for other languages. Reference implementation with extraction, edge_imports and sequential + parallel pipeline tests (first commit of the branch, ~320 src / ~230 test lines):
https://github.com/htarnacki/codebase-memory-mcp/tree/feat/scala-receiver-resolution

This is the base for the follow-up Scala items (companion objects, receiver-aware suppression, typed receivers, super) which I am filing as separate issues; they stack on this one.

Alternatives considered

  • Keep directory-based namespaces and only special-case aliases: still wrong whenever package and path diverge, which is the common case in sbt multi-module builds.

Confirmations

  • I searched existing issues and this is not a duplicate.

Activity

  1. added
    bugSomething isn't working
    priority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.
    on Sep 19, 2026
  2. DeusData commented on Sep 25, 2026

    @DeusData
    Owner

    Hi @htarnacki, thank you for such a thorough write-up, and for already building a reference implementation with sequential and parallel pipeline tests. The snippet and the expected output make the gap very clear.

    Today Scala imports go through the generic fallback, and the namespace comes from the directory rather than the package clause, so sbt multi-module layouts get wrong or missing IMPORTS and CALLS edges. Parsing selectors, aliases and wildcards, and resolving against the declared package first, is the right direction. Keeping every other language unchanged is exactly the constraint we want.

    Since you've already done the work and plan to stack the follow-up Scala items on it, we'd much rather merge your change than re-implement it. Would you open the first commit of feat/scala-receiver-resolution as its own PR against main, scoped to #2153? The companion-object, receiver and super pieces can then follow as separate PRs on top.

    When you do, please include a quick before/after of IMPORTS and CALLS resolution on a real Scala project (any popular OSS repo is fine), so we can check the new edges for false positives. Thanks again for all the Scala work!

  3. htarnacki commented on Sep 26, 2026

    @htarnacki
    ContributorAuthor

    Opened #2360 with the before/after on twitter/finagle as requested.

  4. added 7 commits that reference this issue on Sep 27, 2026
    09f704d
    06ef2f6
    5a77358
    bb3f1cd
    4a0f966
    a5652ee
    bff50fe
  5. DeusData commented on Oct 19, 2026

    @DeusData
    Owner

    Thank you for opening #2360 and supplying the requested finagle comparison. The next review remains on the maintainer side; I have no new verified status or additional information request today.

  6. DeusData commented on Oct 25, 2026

    @DeusData
    Owner

    Thank you for #2360 and the requested finagle comparison. The next review remains on our side. Sorry for the delay; I’ll follow up soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingparsing/qualityGraph extraction bugs, false positives, missing edgespriority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions