@@ -314,13 +314,19 @@ object messages {
314
314
315
315
val msg : String = {
316
316
import core .Flags ._
317
- val maxDist = 3
318
- val decls = site.decls.toList
319
- .filter(_.isType == name.isTypeName)
320
- .flatMap { sym =>
321
- if (sym.flagsUNSAFE.isOneOf(Synthetic | PrivateLocal ) || sym.isConstructor) Nil
322
- else List ((sym.name.show, sym))
323
- }
317
+ val maxDist = 3 // maximal number of differences to be considered for a hint
318
+ val missing = name.show
319
+
320
+ // The names of all non-synthetic, non-private members of `site`
321
+ // that are of the same type/term kind as the missing member.
322
+ def candidates : Set [String ] =
323
+ for
324
+ bc <- site.baseClasses.toSet
325
+ sym <- bc.info.decls.filter(sym =>
326
+ sym.isType == name.isTypeName
327
+ && ! sym.isConstructor
328
+ && ! sym.flagsUNSAFE.isOneOf(Synthetic | Private ))
329
+ yield sym.name.show
324
330
325
331
// Calculate Levenshtein distance
326
332
def distance (n1 : Iterable [? ], n2 : Iterable [? ]) =
@@ -333,37 +339,18 @@ object messages {
333
339
}
334
340
}.last
335
341
336
- // Count number of wrong characters
337
- def incorrectChars (x : (String , Int , Symbol )): (String , Symbol , Int ) = {
338
- val (currName, _, sym) = x
339
- val matching = name.show.zip(currName).foldLeft(0 ) {
340
- case (acc, (x,y)) => if (x != y) acc + 1 else acc
341
- }
342
- (currName, sym, matching)
343
- }
344
-
345
- // Get closest match in `site`
346
- def closest : List [String ] =
347
- decls
348
- .map { (n, sym) => (n, distance(n, name.show), sym) }
349
- .collect {
350
- case (n, dist, sym)
351
- if dist <= maxDist && dist < (name.toString.length min n.length) =>
352
- (n, dist, sym)
353
- }
354
- .groupBy(_._2).toList
355
- .sortBy(_._1)
356
- .headOption.map(_._2).getOrElse(Nil )
357
- .map(incorrectChars).toList
358
- .sortBy(_._3)
359
- .map(_._1)
360
- // [Martin] Note: I have no idea what this does. This shows the
361
- // pitfalls of not naming things, functional or not.
342
+ // A list of possible candidate strings with their Levenstein distances
343
+ // to the name of the missing member
344
+ def closest : List [(Int , String )] = candidates
345
+ .toList
346
+ .map(n => (distance(n.show, missing), n))
347
+ .filter((d, n) => d <= maxDist && d < missing.length & d < n.length)
348
+ .sorted // sort by distance first, alphabetically second
362
349
363
350
val finalAddendum =
364
351
if addendum.nonEmpty then addendum
365
352
else closest match {
366
- case n :: _ =>
353
+ case (d, n) :: _ =>
367
354
val siteName = site match
368
355
case site : NamedType => site.name.show
369
356
case site => i " $site"
0 commit comments