From 9e8761c4402ddc11c942ed2e583bd7d58f70c5ea Mon Sep 17 00:00:00 2001
From: Jean Chalard <jchalard@google.com>
Date: Wed, 14 Dec 2011 20:13:16 +0900
Subject: [PATCH] Reorganize the auto-correction memory

Change-Id: I31cce9db471dcd4a7b3477bcb037a8ff482b7696
---
 .../android/inputmethod/latin/LatinIME.java   | 31 +++++--------
 .../inputmethod/latin/WordComposer.java       | 45 +++++++++++--------
 2 files changed, 38 insertions(+), 38 deletions(-)

diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 59d394b5ef..60f8ce8d8d 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -199,7 +199,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
     private WordComposer mWordComposer = new WordComposer();
 
     private int mCorrectionMode;
-    private String mWordSavedForAutoCorrectCancellation;
     // Keep track of the last selection range to decide if we need to show word alternatives
     private int mLastSelectionStart;
     private int mLastSelectionEnd;
@@ -1308,8 +1307,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
         mKeyboardSwitcher.updateShiftState();
         mKeyboardSwitcher.onCodeInput(Keyboard.CODE_DUMMY);
         mSpaceState = SPACE_STATE_NONE;
-        mWordSavedForAutoCorrectCancellation = null;
         mEnteredText = text;
+        mWordComposer.reset();
     }
 
     @Override
@@ -1363,13 +1362,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
                 ic.deleteSurroundingText(1, 0);
             }
         } else {
-            if (null != mWordSavedForAutoCorrectCancellation) {
+            if (mWordComposer.didAutoCorrectToAnotherWord()) {
                 Utils.Stats.onAutoCorrectionCancellation();
                 cancelAutoCorrect(ic);
-                mWordSavedForAutoCorrectCancellation = null;
                 return;
-            } else {
-                mWordSavedForAutoCorrectCancellation = null;
             }
 
             if (SPACE_STATE_DOUBLE == spaceState) {
@@ -1524,9 +1520,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
         if (ic != null) {
             ic.beginBatchEdit();
         }
-        // Reset the saved word in all cases. If this separator causes an autocorrection,
-        // it will overwrite this null with the actual word we need to save.
-        mWordSavedForAutoCorrectCancellation = null;
         if (mWordComposer.isComposingWord()) {
             // In certain languages where single quote is a separator, it's better
             // not to auto correct, but accept the typed word. For instance,
@@ -1810,9 +1803,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
             Utils.Stats.onAutoCorrection(typedWord, autoCorrection.toString(), separatorCodePoint);
             mExpectingUpdateSelection = true;
             commitBestWord(autoCorrection);
-            if (!autoCorrection.equals(typedWord)) {
-                mWordSavedForAutoCorrectCancellation = autoCorrection.toString();
-            }
             // Add the word to the user unigram dictionary if it's not a known word
             addToUserUnigramAndBigramDictionaries(autoCorrection,
                     UserUnigramDictionary.FREQUENCY_FOR_TYPED);
@@ -2103,28 +2093,31 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
 
     // "ic" must not be null
     private void cancelAutoCorrect(final InputConnection ic) {
-        final int cancelLength = mWordSavedForAutoCorrectCancellation.length();
+        mWordComposer.resumeSuggestionOnKeptWord();
+        final String originallyTypedWord = mWordComposer.getTypedWord();
+        final CharSequence autoCorrectedTo = mWordComposer.getAutoCorrectionOrNull();
+        final int cancelLength = autoCorrectedTo.length();
         final CharSequence separator = ic.getTextBeforeCursor(1, 0);
         if (DEBUG) {
             final String wordBeforeCursor =
                     ic.getTextBeforeCursor(cancelLength + 1, 0).subSequence(0, cancelLength)
                     .toString();
-            if (!mWordSavedForAutoCorrectCancellation.equals(wordBeforeCursor)) {
+            if (!autoCorrectedTo.equals(wordBeforeCursor)) {
                 throw new RuntimeException("cancelAutoCorrect check failed: we thought we were "
-                        + "reverting \"" + mWordSavedForAutoCorrectCancellation
+                        + "reverting \"" + autoCorrectedTo
                         + "\", but before the cursor we found \"" + wordBeforeCursor + "\"");
             }
-            if (mWordComposer.getTypedWord().equals(wordBeforeCursor)) {
+            if (originallyTypedWord.equals(wordBeforeCursor)) {
                 throw new RuntimeException("cancelAutoCorrect check failed: we wanted to cancel "
-                        + "auto correction and revert to \"" + mWordComposer.getTypedWord()
+                        + "auto correction and revert to \"" + originallyTypedWord
                         + "\" but we found this very string before the cursor");
             }
         }
         ic.deleteSurroundingText(cancelLength + 1, 0);
-        mWordComposer.resumeSuggestionOnKeptWord();
-        ic.commitText(mWordComposer.getTypedWord(), 1);
+        ic.commitText(originallyTypedWord, 1);
         // Re-insert the separator
         ic.commitText(separator, 1);
+        mWordComposer.deleteAutoCorrection();
         mWordComposer.onCommitWord();
         Utils.Stats.onSeparator(separator.charAt(0), WordComposer.NOT_A_COORDINATE,
                 WordComposer.NOT_A_COORDINATE);
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index 9d6803ef23..54d9080111 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -16,6 +16,8 @@
 
 package com.android.inputmethod.latin;
 
+import android.text.TextUtils;
+
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.KeyDetector;
 import com.android.inputmethod.keyboard.Keyboard;
@@ -40,12 +42,14 @@ public class WordComposer {
         int[] mXCoordinates;
         int[] mYCoordinates;
         StringBuilder mTypedWord;
+        CharSequence mAutoCorrection;
         CharacterStore() {
             final int N = BinaryDictionary.MAX_WORD_LENGTH;
             mCodes = new ArrayList<int[]>(N);
             mTypedWord = new StringBuilder(N);
             mXCoordinates = new int[N];
             mYCoordinates = new int[N];
+            mAutoCorrection = null;
         }
         CharacterStore(final CharacterStore that) {
             mCodes = new ArrayList<int[]>(that.mCodes);
@@ -57,15 +61,14 @@ public class WordComposer {
             // For better performance than creating a new character store.
             mCodes.clear();
             mTypedWord.setLength(0);
+            mAutoCorrection = null;
         }
     }
 
     // The currently typing word. May not be null.
     private CharacterStore mCurrentWord;
     // The information being kept for resuming suggestion. May be null if wiped.
-    private CharacterStore mWordKeptForSuggestionResuming;
-    // An auto-correction for this word out of the dictionary.
-    private CharSequence mAutoCorrection;
+    private CharacterStore mCommittedWordSavedForSuggestionResuming;
 
     private int mCapsCount;
 
@@ -80,9 +83,8 @@ public class WordComposer {
 
     public WordComposer() {
         mCurrentWord = new CharacterStore();
-        mWordKeptForSuggestionResuming = null;
+        mCommittedWordSavedForSuggestionResuming = null;
         mTrailingSingleQuotesCount = 0;
-        mAutoCorrection = null;
     }
 
     public WordComposer(WordComposer source) {
@@ -91,12 +93,11 @@ public class WordComposer {
 
     public void init(WordComposer source) {
         mCurrentWord = new CharacterStore(source.mCurrentWord);
-        mWordKeptForSuggestionResuming = source.mWordKeptForSuggestionResuming;
+        mCommittedWordSavedForSuggestionResuming = source.mCommittedWordSavedForSuggestionResuming;
         mCapsCount = source.mCapsCount;
         mIsFirstCharCapitalized = source.mIsFirstCharCapitalized;
         mAutoCapitalized = source.mAutoCapitalized;
         mTrailingSingleQuotesCount = source.mTrailingSingleQuotesCount;
-        mAutoCorrection = null;
     }
 
     /**
@@ -104,11 +105,10 @@ public class WordComposer {
      */
     public void reset() {
         mCurrentWord.reset();
-        mWordKeptForSuggestionResuming = null;
+        mCommittedWordSavedForSuggestionResuming = null;
         mCapsCount = 0;
         mIsFirstCharCapitalized = false;
         mTrailingSingleQuotesCount = 0;
-        mAutoCorrection = null;
     }
 
     /**
@@ -167,7 +167,7 @@ public class WordComposer {
         } else {
             mTrailingSingleQuotesCount = 0;
         }
-        mAutoCorrection = null;
+        mCurrentWord.mAutoCorrection = null;
     }
 
     /**
@@ -201,7 +201,7 @@ public class WordComposer {
             int codePoint = word.charAt(i);
             addKeyInfo(codePoint, keyboard, keyDetector);
         }
-        mAutoCorrection = null;
+        mCommittedWordSavedForSuggestionResuming = null;
     }
 
     /**
@@ -253,7 +253,7 @@ public class WordComposer {
                 ++mTrailingSingleQuotesCount;
             }
         }
-        mAutoCorrection = null;
+        mCurrentWord.mAutoCorrection = null;
     }
 
     /**
@@ -312,37 +312,44 @@ public class WordComposer {
      * Sets the auto-correction for this word.
      */
     public void setAutoCorrection(final CharSequence correction) {
-        mAutoCorrection = correction;
+        mCurrentWord.mAutoCorrection = correction;
     }
 
     /**
      * Remove any auto-correction that may have been set.
      */
     public void deleteAutoCorrection() {
-        mAutoCorrection = null;
+        mCurrentWord.mAutoCorrection = null;
     }
 
     /**
      * @return the auto-correction for this word, or null if none.
      */
     public CharSequence getAutoCorrectionOrNull() {
-        return mAutoCorrection;
+        return mCurrentWord.mAutoCorrection;
     }
 
     // TODO: pass the information about what was committed and how. Was it an auto-correction?
     // Was it a completion? Was is what the user typed?
     public void onCommitWord() {
-        mWordKeptForSuggestionResuming = mCurrentWord;
+        mCommittedWordSavedForSuggestionResuming = mCurrentWord;
         // TODO: improve performance by swapping buffers instead of creating a new object.
         mCurrentWord = new CharacterStore();
     }
 
     public boolean hasWordKeptForSuggestionResuming() {
-        return null != mWordKeptForSuggestionResuming;
+        return null != mCommittedWordSavedForSuggestionResuming;
     }
 
     public void resumeSuggestionOnKeptWord() {
-        mCurrentWord = mWordKeptForSuggestionResuming;
-        mWordKeptForSuggestionResuming = null;
+        mCurrentWord = mCommittedWordSavedForSuggestionResuming;
+        mCommittedWordSavedForSuggestionResuming = null;
+    }
+
+    public boolean didAutoCorrectToAnotherWord() {
+        return null != mCommittedWordSavedForSuggestionResuming
+                && !TextUtils.isEmpty(mCommittedWordSavedForSuggestionResuming.mAutoCorrection)
+                && !TextUtils.equals(mCommittedWordSavedForSuggestionResuming.mTypedWord,
+                        mCommittedWordSavedForSuggestionResuming.mAutoCorrection);
     }
 }
-- 
GitLab