From 2ca1ddf7d3d5d8f68fb2d6d1341bf85b265ccbec Mon Sep 17 00:00:00 2001 From: LeanBitLab <245915690+LeanBitLab@users.noreply.github.com> Date: Tue, 20 Oct 2026 10:23:17 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=B9=20Sentinel:=20Remove=20unused=20on?= =?UTF-8?q?DeleteMultiCharInput=20method?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed the empty and unused `onDeleteMultiCharInput` method from `StatsUtils.kt` to keep the codebase clean and reduce maintenance overhead. This method had no active callers. --- .jules/bolt.md | 26 ---------------- .jules/modernizer.md | 3 -- .jules/sentinel.md | 3 -- .jules/shield.md | 31 ------------------- .../keyboard/latin/utils/StatsUtils.kt | 3 -- 5 files changed, 66 deletions(-) delete mode 100644 .jules/bolt.md delete mode 100644 .jules/modernizer.md delete mode 100644 .jules/sentinel.md delete mode 100644 .jules/shield.md diff --git a/.jules/bolt.md b/.jules/bolt.md deleted file mode 100644 index f778fe2d9..000000000 --- a/.jules/bolt.md +++ /dev/null @@ -1,26 +0,0 @@ -## 2024-05-18 - Language Detector Optimization -**Learning:** `LanguageDetector.detect` uses `Regex("[^\\p{L}]+")` inside `detectByHeuristics`, creating a new Regex instance on every call. This method is called via `ProofreadHelper` which is likely triggered on user typing or interaction. Pre-compiling the Regex as a top-level constant avoids the overhead of regex compilation for every detection call. -**Action:** Always check for repeated Regex instantiations in frequently called string processing or detection methods and extract them to top-level or companion object properties. -## 2024-05-18 - StringUtils Whitespace Split Optimization -**Learning:** `StringUtils.splitOnWhitespace` creates a `Regex("\\s+")` inline every time it is called. Since this is an extension function used across settings and text processing, this causes unnecessary allocations. -**Action:** Abstract frequent inline regex usages into `private val` properties at the object or file level to avoid repeated regex compilation. - -## 2024-05-18 - Pre-compile Regex in hot dictionary loops -**Learning:** Instantiating `Regex` objects inside dictionary processing loops (like adding words in `UserBinaryDictionary` or `AppsBinaryDictionary`) causes unnecessary allocations and compilation overhead on every item iteration. -**Action:** Always pre-compile `Regex` objects as `private val` properties in the class or companion object to eliminate per-iteration compilation and allocation pressure. - -## 2024-05-18 - Pre-compile Regex in model importers -**Learning:** `TranslationModelImporter` and `HandwritingModelImporter` create `Regex` instances inside `detectLanguageCode` and `detectLanguageTag` methods, sometimes inside a loop parsing zip entries. This causes unnecessary overhead on every detection call. -**Action:** Extract frequently used `Regex` instances into `companion object`s as `private val`s to ensure they are compiled only once, reducing execution time and object allocation. -## 2024-05-18 - Pre-compile Regex in SpellCheckerSession -**Learning:** `AndroidWordLevelSpellCheckerSession` previously instantiated new `Regex` objects for every quote matching and punctuation splitting operation during `onGetSuggestionsInternal`, which is a highly invoked method on the spellchecker hot-path. -**Action:** Always extract frequently instantiated `Regex` objects from hot paths (like text replacement or splitting) into `companion object` private constants (e.g. `periodRegex`, `quotesStartRegex`) to reduce allocation and regex compilation overhead per keystroke. -## 2024-05-18 - Pre-compile Regex in VoiceInputManager -**Learning:** `VoiceInputManager.syncRecognizedText` instantiates `Regex("[,.?!;:]")` inside a frequent method call, increasing allocation pressure on voice typing hot paths. -**Action:** Extract repeated `Regex` instantiations in input hot paths (such as `syncRecognizedText`) into companion object private constants to reduce memory allocation and compilation overhead. -## 2024-05-18 - Pre-compile Regex in OCR formatting -**Learning:** `OcrTextFormatter.formatLines` instantiated `Regex` for bullet removal inline every time it was called when `stripBullets` was true. This causes unnecessary allocation and compilation overhead when parsing OCR lines. -**Action:** Extract frequently used formatting regexes (such as `bulletRegex`) into `object` or companion object private constants (`private val BULLET_REGEX`) to optimize regex reuse and eliminate unnecessary compilation per text parsing operation. -## 2024-05-18 - Optimize Diacritic Stripping in Suggest -**Learning:** In `Suggest.isSameIgnoringAccents`, `val DIACRITIC_REGEX = "\\p{M}+".toRegex()` was being used in combination with `Normalizer.normalize` and `replace` to strip accents. This created string allocations via `Normalizer.normalize` and `Regex.replace` even for plain ASCII strings that lack accents, which is a hot path during typing and suggestion processing. -**Action:** Replace `Regex.replace` with a manual character loop that avoids `Normalizer.normalize` entirely for pure ASCII strings and strips `Character.NON_SPACING_MARK` without regex allocation when normalizing. diff --git a/.jules/modernizer.md b/.jules/modernizer.md deleted file mode 100644 index 446038e72..000000000 --- a/.jules/modernizer.md +++ /dev/null @@ -1,3 +0,0 @@ -## 2024-05-15 - Migrate SponsorDialog to PreferenceDialog -**Learning:** Legacy UI builder paradigms (like using a raw Compose `Dialog` wrapper around `Card` + `Column`) often duplicate layout boilerplate that the `PreferenceDialog` standard component encapsulates perfectly. -**Action:** When discovering custom standalone dialog implementations without standard scaffolding, prefer wrapping their content in `PreferenceDialog` (using the `buttons` and `content` slots) to enforce consistent margin, shape, and background settings uniformly across the settings screens. diff --git a/.jules/sentinel.md b/.jules/sentinel.md deleted file mode 100644 index 7ff762f22..000000000 --- a/.jules/sentinel.md +++ /dev/null @@ -1,3 +0,0 @@ -## 2024-10-24 - Dynamic drawable lookups -**Learning:** Drawables can be referenced dynamically by name through `Settings.customIconIds` and `context.resources.getIdentifier` as seen in `custom_icon_names`. -**Action:** Never delete drawables (especially `ic_*` icons) without explicitly checking if they are intended for dynamic or user-customizable icon settings. diff --git a/.jules/shield.md b/.jules/shield.md deleted file mode 100644 index 81f4944fe..000000000 --- a/.jules/shield.md +++ /dev/null @@ -1,31 +0,0 @@ -## 2024-10-24 - Surrogate pairs and Character.isLetter in WordTokenizer -**Learning:** `Character.isLetter(char)` does not reliably handle emojis or characters outside the BMP (Basic Multilingual Plane) that are encoded as 2-character surrogate pairs. When iterating string arrays or performing substring lookups on indexes, accessing a single `char` of a 2-char pair (e.g. `word[apostropheIdx - 1]`) to evaluate `Character.isLetter` will erroneously return false, as it only evaluates the surrogate half rather than the complete character. -**Action:** When testing or validating components involving boundary lookups around punctuation (like in `isContraction` or split logic), always include unit tests with Unicode characters outside the BMP (such as Deseret capital letters like `\uD801\uDC37` or emojis) to document the runtime behavior and protect against regressions, regardless of if the current implementation has limitations. - -## 2025-02-15 - Unit tests for CapsModeUtils -**Learning:** Testing string utility logic like CapsModeUtils can still require the Robolectric framework since it often depends on Android-specific classes like `android.text.TextUtils` under the hood. Furthermore, checking combinations of logical states inside complex state machines like text capitalizer logic requires detailed parameter combinations, especially regarding abbreviation marker flags and German rule configurations. -**Action:** When adding tests for classes that wrap around Android framework components such as `TextUtils`, `InputType`, or `Locale` classes, explicitly use `@RunWith(RobolectricTestRunner::class)` even for seemingly pure string logic utilities, to prevent missing framework components runtime exceptions. - -## 2025-02-17 - Unit tests for ScriptUtils -**Learning:** Testing string utility logic involving scripts requires careful consideration of unsupported or invalid fallback scripts. For instance, testing `Locale("ja").script()` reveals that `ScriptUtils` gracefully falls back to `SCRIPT_LATIN` rather than breaking, even though Japanese is unsupported. -**Action:** When creating tests for locale scripts or handling unknown/fallback contexts, include assertions to verify that invalid configurations gracefully fallback or throw exactly the expected exception without leaking framework level crashes. - -## 2025-02-17 - Unit tests for InputTypeUtils -**Learning:** Utilities that parse input type flags often depend on standard constants in `InputType` and `EditorInfo`. Furthermore, checking states often requires understanding package quirks loaded through `AppQuirksManager`. Running these tests efficiently without manually setting up the entire mock context is possible by relying on Robolectric, as it correctly handles `android.view.inputmethod.EditorInfo` instantiation and flag masking for text parsing. -**Action:** When adding unit tests for utilities handling input frameworks (such as `InputTypeUtils`), explicitly use `@RunWith(RobolectricTestRunner::class)` to handle dependencies on `EditorInfo` and framework constants, and ensure you cover edge cases involving bits masked out by classes (e.g. `TYPE_MASK_CLASS` vs `TYPE_MASK_VARIATION`). - -## 2025-02-18 - Unit tests for TextRange -**Learning:** Testing classes that manipulate or read from Android `Spanned` texts and `SuggestionSpan` objects (such as `TextRange.getSuggestionSpansAtWord()`) requires dependencies from the Android Framework. These dependencies handle bounds tracking, flag masking, and class resolutions dynamically within the spannable object. -**Action:** When adding tests for text and span manipulation logic, use `@RunWith(RobolectricTestRunner::class)` to provide a complete and functional implementation of the `Spanned` interface and avoid `NoClassDefFoundError` or `NullPointerException` errors during span retrieval operations. - -## 2025-02-18 - Unit tests for CombinedFormatUtils -**Learning:** Utilities formatting internal configurations (like dictionaries and probability info mapping to files or logging systems) might combine multiple attributes where edge cases (such as missing dict IDs, missing ngram info, or empty shortcuts) aren't immediately clear from the method signature. Testing `CombinedFormatUtils` proves that when writing string-manipulation utility tests, testing all internal property flags correctly formats the output exactly as specified by dictionary protocol constants. -**Action:** When adding tests for utility formatters or string builders used for file protocols or dictionary formats, always add comprehensive branch coverage for flag values (e.g., `not_a_word=true`, `historicalInfo`, and absence of ID keys) as boundary values, and avoid mock frameworks by using concrete instances of domain objects like `WordProperty` and `ProbabilityInfo` where possible. - -## 2025-02-18 - Unit tests for LocaleUtils -**Learning:** Testing string utility logic for formatting configuration and tracking variables often depends on core frameworks. LocaleUtils modifies global device Context configurations based on language, which requires a complete runtime to correctly set and interact with `android.content.res.Configuration` and Context. Using Robolectric provides a functional implementation of these properties. -**Action:** When testing classes operating on Android Context extensions and locale configurations, use `@RunWith(RobolectricTestRunner::class)` to bypass null or unimplemented pointer errors and seamlessly interact with resource contexts without extensive mocking. - -## 2025-02-18 - Unit tests for LanguageDetector -**Learning:** Testing string utility logic for language detection requires broad Unicode support. Testing these cases with Robolectric is useful because `LanguageDetector` depends on Android classes such as `android.view.textclassifier.TextClassificationManager` for fallback capabilities. -**Action:** When adding tests for string utility logic involving language detection that uses Android framework features, use `@RunWith(RobolectricTestRunner::class)` to safely handle any dependencies on framework components like `TextClassificationManager`. diff --git a/app/src/main/java/helium314/keyboard/latin/utils/StatsUtils.kt b/app/src/main/java/helium314/keyboard/latin/utils/StatsUtils.kt index 6f5123bb9..ec373c2ee 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/StatsUtils.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/StatsUtils.kt @@ -34,9 +34,6 @@ object StatsUtils { fun onBackspaceSelectedText(selectedTextLength: Int) { } - fun onDeleteMultiCharInput(multiCharLength: Int) { - } - fun onRevertAutoCorrect() { }