Skip to content

[index] SymbolId.fromSemanticDb on trailing-/ package symbols produces empty-name term id #74

Description

@rochala

Severity: low — degenerate output on inputs that current callers don't generate, but the silent failure mode is bad if a future caller emits one.

Symptom

SymbolId.fromSemanticDb treats anything not ending in # as a term:

val isType = if classPart.endsWith("#") then true else false

For SemanticDB inputs that end in / (package symbols like scala/collection/) or other unexpected sigils (e.g. [T] for type arguments), the classifier wrongly defaults to term. The parser then strips one #/. (no-op for trailing-/) and tokenises by [.#], returning empty tokens for a trailing-/ package.

fromSemanticDb("scala/collection/")pkg=["scala","collection"], classPart="", tokens=Nil → returns SymbolId(pkg, Nil, "", None) — a term id with empty name. Map lookups by this id would collide across all such cases.

Fix

Recognise SemanticDB sentinels explicitly and return either a sentinel-discriminated id or skip outright. Sketch:

def fromSemanticDb(sdbSymbol: String): SymbolId = {
  val cleaned = sdbSymbol.replaceAll("\\(\\+?\\d*\\)", "")
  if cleaned.isEmpty then return SymbolId(Nil, Nil, "", None)
  if cleaned.endsWith("/") then {
    // Package symbol — encode the trailing segment as the name with member=None.
    val pkgs = cleaned.stripSuffix("/").split('/').toList.filter(_.nonEmpty)
    return pkgs match {
      case Nil    => SymbolId(Nil, Nil, "", None)
      case many   => SymbolId.tpe(many.init, Nil, many.last)
    }
  }
  // ... rest of current implementation, but assert classPart non-empty before tokenising
}

Decide whether package symbols should round-trip through fromSemanticDb at all — they may not be a real use case for find-references. If not, log + return a sentinel instead.

Acceptance criteria

  • fromSemanticDb("scala/collection/") returns something non-degenerate (either tpe(["scala"], Nil, "collection") or an explicit sentinel)
  • Decision documented in the factory docstring

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions