Class QuickFixSuggestionExtractor
Suggestion list combining two strategies:
- Common-literal / keyword pool — Levenshtein-near matches against
a small fixed pool of EK9 keywords, literals, and common type names.
Catches user typos (e.g.
flase→false,treu→true) that the symbol table can't help with because keywords aren't symbols. - Fuzzy symbol matches — symbol-table search results, FILTERED by
a Levenshtein-cost threshold AND a length-diff threshold relative to
the offending token. Without these filters the search returns whatever
the closest k symbols were even when irrelevant (e.g.
flase→Class1/Class2).
Parse-message expected tokens (e.g. ANTLR's "expecting 'defines', '@'")
are deliberately NOT included. They're already rendered in the inline
typeOfError text the parser produces, so adding a separate
"did you mean: '@'?" line is redundant noise. Kept out of all output
channels — CLI classic, CLI visual, IDE Problems tooltip, IDE Quick Fix
popup, MCP ek9_query_diagnostics.
Results are ranked by:
- Character-bag overlap descending — the strongest typo signal
(chars in common). For
flase,falseshares all 5 unique chars (perfect anagram) and ranks first. - Same-length first (length-diff ascending) — typos rarely change length
- Cost ascending — Levenshtein closeness as fine-grained tiebreak
- Source priority: parse-token > keyword > symbol
- Alphabetical (deterministic)
Bag-overlap-primary is correct over cost-primary because the existing
EK9 Levenshtein cost metric has a boundary anomaly (insertion
cost 1 along the edge but 2 in the body) that under-charges length-mismatch
candidates. For flase, raw cost gives case=3 (gaming the
boundary) but false=4 — wrong winner. Bag-overlap captures the
"shares the same letters" signal that actually matters for typo correction.
-
Method Summary
Modifier and TypeMethodDescriptionstatic List<Suggestion> Build the ranked, filtered suggestion list for an error.Convenience: list of bare replacement names.static StringFormat a suggestion list as the inline "Did you mean: X, Y, Z?" string used byErrorListener.ErrorDetails.toString()(CLI classic mode).(package private) static List<org.ek9lang.compiler.common.QuickFixSuggestionExtractor.RankedSuggestion> Backing list helper kept for tests that want the raw flat list.
-
Method Details
-
extract
Build the ranked, filtered suggestion list for an error. Capped at 5 entries.Keyword-pool and fuzzy-symbol matches only run when the compiler signalled "this error might be a typo" by attaching a non-null
fuzzySearchResultsobject. Errors likeE07370 Unreachable Statementcarry a validlikelyOffendingSymbol(the unreachable label) but no fuzzy context — they shouldn't get "Did you mean?" noise. Parse-message tokens always run since they come from the parser's own grammar knowledge. -
extractNames
Convenience: list of bare replacement names. Used by IDE quick-fix popups and by AI clients requesting unstructured fix data. -
formatForErrorMessage
Format a suggestion list as the inline "Did you mean: X, Y, Z?" string used byErrorListener.ErrorDetails.toString()(CLI classic mode). Returns the empty string when there are no suggestions. -
rankedListForTests
static List<org.ek9lang.compiler.common.QuickFixSuggestionExtractor.RankedSuggestion> rankedListForTests(ErrorListener.ErrorDetails error) Backing list helper kept for tests that want the raw flat list. Hidden because consumers should preferextract(ErrorListener.ErrorDetails)orextractNames(ErrorListener.ErrorDetails).
-