@@ -954,55 +954,49 @@ export function dedupeSuggestions(
954954export function processSimilarity (
955955 lexicalModel : LexicalModel ,
956956 suggestionDistribution : IntermediateCompositedPrediction [ ] ,
957- context : Context ,
958- trueInput : ProbabilityMass < Transform >
957+ baseContext : Context ,
958+ finalContext : Context
959959) : boolean {
960- const { sample : inputTransform } = trueInput ;
961960 const wordbreak = determineModelWordbreaker ( lexicalModel ) ;
962961
963- const postContext = models . applyTransform ( inputTransform , context ) ;
964- const truePrefix = wordbreak ( postContext ) ;
965-
966962 const keyed = ( text : string ) => lexicalModel . toKey ? lexicalModel . toKey ( text ) : text ;
967963 const keyCased = ( text : string ) => lexicalModel . applyCasing ? lexicalModel . applyCasing ( 'lower' , text ) : text ;
968- const keyedPrefix = keyed ( truePrefix ) ;
969- const lowercasedPrefix = keyCased ( truePrefix ) ;
964+ const keyedTarget = keyed ( finalContext . left ) ;
965+ const lowercasedTarget = keyCased ( finalContext . left ) ;
970966
971967 let keepOption : Outcome < Keep > ;
972968
973- for ( let tuple of suggestionDistribution ) {
974- // Don't set it unnecessarily; this can have side-effects in some automated tests .
975- if ( inputTransform . id !== undefined ) {
976- tuple . components . prediction . transformId = inputTransform . id ;
977- }
969+ // If there are no suggestions found, we can't validate that the underlying
970+ // correction was an empty token .
971+ let allCorrectionsEmpty : boolean = suggestionDistribution . length > 0
972+ ? true
973+ : wordbreak ( finalContext ) == '' ;
978974
979- const predictedWord = wordbreak ( models . applyTransform ( tuple . components . prediction . transform , context ) ) ;
975+ for ( let tuple of suggestionDistribution ) {
976+ const appliedContext = models . applyTransform ( tuple . components . prediction . transform , baseContext ) ;
977+ allCorrectionsEmpty &&= tuple . components . correction == '' ;
980978
981979 // Is the suggestion an exact match (or, "similar enough") to the
982980 // actually-typed context? If so, we wish to note this fact and to
983981 // prioritize such a suggestion over suggestions that are not.
984- if ( keyed ( tuple . components . correction ) == keyedPrefix ) {
985- if ( predictedWord == truePrefix ) {
986- // Exact match: it's a perfect 'keep' suggestion.
987- tuple . metadata . matchLevel = SuggestionSimilarity . exact ;
988- keepOption = toAnnotatedSuggestion ( lexicalModel , tuple . components . prediction , 'keep' , models . QuoteBehavior . noQuotes ) ;
989-
990- // Indicates that this suggestion exists directly within the lexical
991- // model as a valid suggestion. (We actively display it if it's an
992- // exact match, but hide it if not, only preserving it for reversions
993- // if/when needed.)
994- keepOption . matchesModel = true ;
995- Object . assign ( tuple . components . prediction , keepOption ) ;
996- keepOption = tuple . components . prediction as Outcome < Keep > ;
997- } else if ( keyCased ( predictedWord ) == lowercasedPrefix ) {
998- // Case-insensitive match. No diacritic differences; the ONLY difference is casing.
999- tuple . metadata . matchLevel = SuggestionSimilarity . sameText ;
1000- } else if ( keyed ( predictedWord ) == keyedPrefix ) {
1001- // Diacritic-insensitive / exact-key match.
1002- tuple . metadata . matchLevel = SuggestionSimilarity . sameKey ;
1003- } else {
1004- tuple . metadata . matchLevel = SuggestionSimilarity . none ;
1005- }
982+ if ( appliedContext . left == finalContext . left ) {
983+ // Exact match: it's a perfect 'keep' suggestion.
984+ tuple . metadata . matchLevel = SuggestionSimilarity . exact ;
985+ keepOption = toAnnotatedSuggestion ( lexicalModel , tuple . components . prediction , 'keep' , models . QuoteBehavior . noQuotes ) ;
986+
987+ // Indicates that this suggestion exists directly within the lexical
988+ // model as a valid suggestion. (We actively display it if it's an
989+ // exact match, but hide it if not, only preserving it for reversions
990+ // if/when needed.)
991+ keepOption . matchesModel = true ;
992+ Object . assign ( tuple . components . prediction , keepOption ) ;
993+ keepOption = tuple . components . prediction as Outcome < Keep > ;
994+ } else if ( keyCased ( appliedContext . left ) == lowercasedTarget ) {
995+ // Case-insensitive match. No diacritic differences; the ONLY difference is casing.
996+ tuple . metadata . matchLevel = SuggestionSimilarity . sameText ;
997+ } else if ( keyed ( appliedContext . left ) == keyedTarget ) {
998+ // Diacritic-insensitive / exact-key match.
999+ tuple . metadata . matchLevel = SuggestionSimilarity . sameKey ;
10061000 } else {
10071001 tuple . metadata . matchLevel = SuggestionSimilarity . none ;
10081002 }
@@ -1012,7 +1006,7 @@ export function processSimilarity(
10121006 //
10131007 // No actual 'keep' needed if the current context token is empty, so we say we
10141008 // have a 'keep' for that case, even though there isn't really one.
1015- return ! ! ( keepOption || truePrefix == '' ) ;
1009+ return ! ! ( keepOption || allCorrectionsEmpty ) ;
10161010}
10171011
10181012/**
0 commit comments