classifyStepTargets function

  1. @visibleForTesting
({List<HintStep> deferred, List<UnknownHintTarget> typos}) classifyStepTargets(
  1. HintTour tour,
  2. Set<String> knownIds
)

Classifies a tour's steps by their target ids (HintStep.targetIds — extras included) against the registry's known ids.

Typo policy:

  • a step referencing an id with candidates (similar ids exist) — a typo: fails loudly in debug, is skipped in release (waiting for it is pointless);
  • a step whose ids are all known or without candidates — a legitimate deferred target: wait, the timeout produces its own diagnosis;
  • an id whose only difference from a candidate is digits (target1/target2 sequences) — also deferred: numeric suffixes are naming, not typos; otherwise every following step in a sequence would look like a typo of the previous one. A pure function: tested directly, applied by the controller.

Implementation

@visibleForTesting
({List<HintStep> deferred, List<UnknownHintTarget> typos}) classifyStepTargets(
    HintTour tour, Set<String> knownIds) {
  final deferred = <HintStep>[];
  final typos = <UnknownHintTarget>[];
  for (var i = 0; i < tour.steps.length; i++) {
    final step = tour.steps[i];
    if (step.targetIds.every(knownIds.contains)) continue; // all known
    String? typoId;
    List<String>? candidates;
    for (final id in step.targetIds) {
      if (knownIds.contains(id)) continue;
      final c = closestTargetIds(id, knownIds);
      if (c.isEmpty || _differsOnlyInDigits(id, c.first)) continue;
      typoId = id;
      candidates = c;
      break;
    }
    if (typoId == null) {
      deferred.add(step);
    } else {
      typos.add((
        step: step,
        index: i,
        typoId: typoId,
        candidates: candidates!,
      ));
    }
  }
  return (deferred: deferred, typos: typos);
}