classifyStepTargets function
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/target2sequences) — 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);
}