Skip to content

Node ids are lower-cased per file: interface Foo and function foo collapse, one is silently dropped #3726

Description

@Charly1000

Node ids are lower-cased per file, so interface Foo and function foo collapse into one node — one of them is silently dropped, and explain then answers with the other.

Version: graphify 0.9.39 (macOS, graphify update . --no-cluster)

Minimal reproducible example

kollision.ts — four top-level declarations, two of which differ only in the case of the first letter (a very common TypeScript idiom: an interface and the function that returns it):

export interface FallListe {
  anzahl: number;
}

export function fallListe(n: number): FallListe {
  return { anzahl: n };
}

export interface Eindeutig {
  wert: string;
}

export function andersBenannt(s: string): Eindeutig {
  return { wert: s };
}

Run:

graphify update . --no-cluster

Expected

Five nodes: the file plus four declarations.

Actual

Four nodes — interface FallListe is missing, with no warning:

  L1    kollision.ts       id=kollision
  L5    fallListe          id=kollision_fallliste
  L9    Eindeutig          id=kollision_eindeutig
  L13   andersBenannt()    id=kollision_andersbenannt

The ids are lower-cased (kollision_fallliste), so FallListe and fallListe produce the same id and one overwrites the other. The control pair in the same file (Eindeutig / andersBenannt, different names) is complete, which isolates the cause to the collision rather than to interfaces in general.

Why this is worse than a missing node

explain does not fail — it answers with the neighbour:

  • graphify explain "FallListe" returns the function.
  • In a real 1900-file repository we hit the same thing twice in one file: graphify explain "TrendUnterschied" (an exported interface) answered with trendUnterschied, the function 80 lines below it, and graphify explain "fallListe" answered with the interface FallListe.

A wrong answer with no error is harder to notice than a missing one, especially when the neighbour is plausible — which it always is here, because the two symbols are about the same thing.

Suggestion

Either preserve case in the id, or keep the lower-cased id for lookup and disambiguate collisions with a suffix (_2, or the node kind). A warning on collision would already help a lot: the current behaviour is indistinguishable from "this symbol is not indexed".

Context

Found while chasing an unrelated warning (#2551, syntax errors from raw NUL bytes in template literals). For the record, the NUL bytes turned out not to cost any nodes — same file with a raw U+0000 and with the `` escape produced identical node sets — so #2551 and this are independent.

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions