Class ConfusinglySimilarNamesOrError

java.lang.Object
org.ek9lang.compiler.phase5.ConfusinglySimilarNamesOrError
All Implemented Interfaces:
Consumer<org.antlr.v4.runtime.tree.ParseTree>

final class ConfusinglySimilarNamesOrError extends Object implements Consumer<org.antlr.v4.runtime.tree.ParseTree>
Detects confusingly similar variable, parameter, and field names within the same scope.

Confusingly similar names are a known comprehension hazard (Aman et al., Empirical Software Engineering 2023, found about 0.86% of compound-name pairs confusingly similar; Wong et al., arXiv 2025). This check flags pairs where:

  • the names are ONE EDIT apart - weightedDistance(String, String) <= 2, where a character inserted, removed or changed ANYWHERE costs 2 (at the start and the end too), two ADJACENT characters swapped (title/titel) cost 2 - but not the first two (latitude/altitude is two changes) - and a change of case costs 1 - or they differ ONLY in case (userID/userid), however many letters (Steve, 2026-10-11)
  • Both have the same type (type system won't catch misuse)
  • Developer controls both names (not inherited/trait methods)

The pairs compared: locals with locals, parameters with parameters, parameters and locals with the enclosing type's properties, and - on the type itself - its own properties with each other.

Intentionally skips:

  • Exact param=field match (common constructor pattern)
  • Different types (type system catches misuse)
  • Loop variables (i, j, k are conventional)
  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    accept(org.antlr.v4.runtime.tree.ParseTree node)
     
    (package private) static int
    THE distance E11030 reports - the weighted edit distance its rich message describes, and nothing else: a character inserted, removed or changed costs 2 wherever it is (the first and last positions included), two ADJACENT characters swapped cost 2 (one edit, as Damerau counts it - title/titel) except at the FIRST letter (positions 0-1), where a swap is two changes (latitude/altitude, 4 - Steve, 2026-10-12), and a change of case alone costs 1.

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

    Methods inherited from interface Consumer

    andThen
  • Constructor Details

  • Method Details

    • accept

      public void accept(org.antlr.v4.runtime.tree.ParseTree node)
      Specified by:
      accept in interface Consumer<org.antlr.v4.runtime.tree.ParseTree>
    • weightedDistance

      static int weightedDistance(String name1, String name2)
      THE distance E11030 reports - the weighted edit distance its rich message describes, and nothing else: a character inserted, removed or changed costs 2 wherever it is (the first and last positions included), two ADJACENT characters swapped cost 2 (one edit, as Damerau counts it - title/titel) except at the FIRST letter (positions 0-1), where a swap is two changes (latitude/altitude, 4 - Steve, 2026-10-12), and a change of case alone costs 1.

      Not org.ek9.lang.Levenshtein.costOfMatch: that is the runtime's fuzzy match, which charges an insertion at the START 1 (so zqname/name came out at 2, one edit) and has no swap. Its asymmetry made the message untrue (lane lang-syntax, fix round 1).