Fix spellcheck on sentence end
Issue:
Valid words are being erroneously flagged by the spellchecker when
followed by a period.
Resolution:
Valid words followed by periods are no longer flagged. Invalid words
followed by periods are still flagged, and the intent behind the
existing logic to flag and suggest valid words on either side of a
period within a token should not be impacted by this change.
Additional considerations for CHECKABILITY_CONTAINS_PERIOD:
* Empty words are considered invalid. In CHECKABILITY_CONTAINS_PERIOD,
when a period was the first or last index of text, splitting that
text on periods caused suggestions to consider potentially valid
words to be invalid. For example, "this.example." should suggest
"this example" or "this example.", but no suggestions were being
given due to the trailing empty string resulting from the split
operation being considered invalid. This PR modifies this behavior
such that empty split tokens will not be considered toward word
validity when generating suggestions for text containing periods.
* Single word sentences (like "Groovy.") were being flagged as invalid
since the word only exists in the main dictionary as lower case, but
the validity check within CHECKABILITY_CONTAINS_PERIOD sent text over
as is. This PR adds, specific to the period checkability logic,
a fallback validity check for words set to lower case.
Fixes: https://gitlab.com/LineageOS/issues/android/-/issues/4861
Change-Id: Ie445533544fb3ed4b8d2fa6b554e03e0ae5a960f
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
index 9223923..00bf9a1 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
@@ -237,16 +237,23 @@
// Handle special patterns like email, URI, telephone number.
final int checkability = getCheckabilityInScript(text, mScript);
if (CHECKABILITY_CHECKABLE != checkability) {
+ // CHECKABILITY_CONTAINS_PERIOD typo should not be reported when text
+ // is a valid word followed by a single period (end of sentence).
+ boolean periodOnlyAtLastIndex = text.indexOf(
+ Constants.CODE_PERIOD) == (text.length() - 1);
if (CHECKABILITY_CONTAINS_PERIOD == checkability) {
final String[] splitText = text.split(Constants.REGEXP_PERIOD);
boolean allWordsAreValid = true;
+ // Validate all words on both sides of periods,
+ // skip empty tokens due to periods at first/last index
for (final String word : splitText) {
- if (!mService.isValidWord(mLocale, word)) {
+ if (!word.isEmpty() && !mService.isValidWord(mLocale, word) &&
+ !mService.isValidWord(mLocale, word.toLowerCase(mLocale))) {
allWordsAreValid = false;
break;
}
}
- if (allWordsAreValid) {
+ if (allWordsAreValid && !periodOnlyAtLastIndex) {
return new SuggestionsInfo(SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO
| SuggestionsInfo.RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS,
new String[] {
@@ -256,7 +263,7 @@
return mService.isValidWord(mLocale, text) ?
AndroidSpellCheckerService.getInDictEmptySuggestions() :
AndroidSpellCheckerService.getNotInDictEmptySuggestions(
- CHECKABILITY_CONTAINS_PERIOD == checkability /* reportAsTypo */);
+ !periodOnlyAtLastIndex);
}
// Handle normal words.