Migrate emoji to use JSpecify annotations
CL created by running `development/jspecify_update.py emoji`
We are updating all AndroidX libraries to use the Jspecify nullness annotations (https://docs.google.com/document/d/1XjainD032hUdCfgXIzRThHvP9FJANYuocKaTDXWuLXo/edit?usp=sharing)
Bug: 326456246
Test: `checkApi`, `lint`, `runErrorProne`
Relnote: "This library now uses [JSpecify nullness annotations](https://jspecify.dev/), which are type-use. Kotlin developers should use the following compiler arguments to enforce correct usage: -Xjspecify-annotations=strict, -Xtype-enhancement-improvements-strict-mode"
Change-Id: Ibb74cbbb710f914213543cc1c6a8273e0e19c4e4
diff --git a/emoji/emoji-appcompat/build.gradle b/emoji/emoji-appcompat/build.gradle
index f29260e..cc3ee69 100644
--- a/emoji/emoji-appcompat/build.gradle
+++ b/emoji/emoji-appcompat/build.gradle
@@ -29,6 +29,7 @@
}
dependencies {
+ api(libs.jspecify)
api(project(":emoji:emoji"))
api("androidx.appcompat:appcompat:1.1.0")
}
diff --git a/emoji/emoji-appcompat/src/main/java/androidx/emoji/widget/EmojiAppCompatEditText.java b/emoji/emoji-appcompat/src/main/java/androidx/emoji/widget/EmojiAppCompatEditText.java
index 31a087d..66ac6ed 100644
--- a/emoji/emoji-appcompat/src/main/java/androidx/emoji/widget/EmojiAppCompatEditText.java
+++ b/emoji/emoji-appcompat/src/main/java/androidx/emoji/widget/EmojiAppCompatEditText.java
@@ -23,10 +23,11 @@
import android.view.inputmethod.InputConnection;
import androidx.annotation.IntRange;
-import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatEditText;
import androidx.emoji.text.EmojiCompat;
+import org.jspecify.annotations.Nullable;
+
/**
* AppCompatEditText widget enhanced with emoji capability by using {@link EmojiEditTextHelper}.
* When used on devices running API 18 or below, this widget acts as a regular
diff --git a/emoji/emoji-bundled/build.gradle b/emoji/emoji-bundled/build.gradle
index d989aea..cf8e119 100644
--- a/emoji/emoji-bundled/build.gradle
+++ b/emoji/emoji-bundled/build.gradle
@@ -24,6 +24,7 @@
}
dependencies {
+ api(libs.jspecify)
api(project(":emoji:emoji"))
}
diff --git a/emoji/emoji-bundled/src/main/java/androidx/emoji/bundled/BundledEmojiCompatConfig.java b/emoji/emoji-bundled/src/main/java/androidx/emoji/bundled/BundledEmojiCompatConfig.java
index cfefdd7..bae6bb2 100644
--- a/emoji/emoji-bundled/src/main/java/androidx/emoji/bundled/BundledEmojiCompatConfig.java
+++ b/emoji/emoji-bundled/src/main/java/androidx/emoji/bundled/BundledEmojiCompatConfig.java
@@ -19,11 +19,12 @@
import android.content.Context;
import android.content.res.AssetManager;
-import androidx.annotation.NonNull;
import androidx.core.util.Preconditions;
import androidx.emoji.text.EmojiCompat;
import androidx.emoji.text.MetadataRepo;
+import org.jspecify.annotations.NonNull;
+
/**
* {@link EmojiCompat.Config} implementation that loads the metadata using AssetManager and
* bundled resources.
@@ -51,7 +52,7 @@
}
@Override
- public void load(@NonNull EmojiCompat.MetadataRepoLoaderCallback loaderCallback) {
+ public void load(EmojiCompat.@NonNull MetadataRepoLoaderCallback loaderCallback) {
Preconditions.checkNotNull(loaderCallback, "loaderCallback cannot be null");
final InitRunnable runnable = new InitRunnable(mContext, loaderCallback);
final Thread thread = new Thread(runnable);
diff --git a/emoji/emoji/build.gradle b/emoji/emoji/build.gradle
index ef6bb11..f6b2e75 100644
--- a/emoji/emoji/build.gradle
+++ b/emoji/emoji/build.gradle
@@ -25,6 +25,7 @@
)
dependencies {
+ api(libs.jspecify)
bundleInside(project(":noto-emoji-compat-flatbuffers"))
api("androidx.core:core:1.3.0")
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/text/FontRequestEmojiCompatConfigTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/text/FontRequestEmojiCompatConfigTest.java
index 3035cf6..f6cfb6c 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/text/FontRequestEmojiCompatConfigTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/text/FontRequestEmojiCompatConfigTest.java
@@ -48,8 +48,6 @@
import android.os.HandlerThread;
import androidx.annotation.GuardedBy;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.core.provider.FontRequest;
import androidx.core.provider.FontsContractCompat.FontFamilyResult;
import androidx.core.provider.FontsContractCompat.FontInfo;
@@ -57,6 +55,8 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
+import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/text/InitCallbackTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/text/InitCallbackTest.java
index cc24436..bf91904 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/text/InitCallbackTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/text/InitCallbackTest.java
@@ -22,11 +22,11 @@
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import androidx.annotation.NonNull;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest;
import androidx.test.platform.app.InstrumentationRegistry;
+import org.jspecify.annotations.NonNull;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -74,7 +74,7 @@
final EmojiCompat.InitCallback initCallback = mock(EmojiCompat.InitCallback.class);
final EmojiCompat.MetadataRepoLoader loader = new EmojiCompat.MetadataRepoLoader() {
@Override
- public void load(@NonNull EmojiCompat.MetadataRepoLoaderCallback loaderCallback) {
+ public void load(EmojiCompat.@NonNull MetadataRepoLoaderCallback loaderCallback) {
loaderCallback.onFailed(new RuntimeException(""));
}
};
@@ -92,7 +92,7 @@
final EmojiCompat.InitCallback initCallback = mock(EmojiCompat.InitCallback.class);
final EmojiCompat.MetadataRepoLoader loader = new EmojiCompat.MetadataRepoLoader() {
@Override
- public void load(@NonNull EmojiCompat.MetadataRepoLoaderCallback loaderCallback) {
+ public void load(EmojiCompat.@NonNull MetadataRepoLoaderCallback loaderCallback) {
loaderCallback.onLoaded(null);
}
};
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/text/TestConfigBuilder.java b/emoji/emoji/src/androidTest/java/androidx/emoji/text/TestConfigBuilder.java
index d5b93ff..7aebe17d 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/text/TestConfigBuilder.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/text/TestConfigBuilder.java
@@ -21,9 +21,10 @@
import android.content.res.AssetManager;
import androidx.annotation.GuardedBy;
-import androidx.annotation.NonNull;
import androidx.test.core.app.ApplicationProvider;
+import org.jspecify.annotations.NonNull;
+
import java.util.concurrent.CountDownLatch;
public class TestConfigBuilder {
@@ -78,7 +79,7 @@
}
@Override
- public void load(@NonNull final EmojiCompat.MetadataRepoLoaderCallback loaderCallback) {
+ public void load(final EmojiCompat.@NonNull MetadataRepoLoaderCallback loaderCallback) {
new Thread(new Runnable() {
@Override
public void run() {
@@ -109,7 +110,7 @@
}
@Override
- public void load(@NonNull EmojiCompat.MetadataRepoLoaderCallback loaderCallback) {
+ public void load(EmojiCompat.@NonNull MetadataRepoLoaderCallback loaderCallback) {
if (sMetadataRepo == null) {
synchronized (sMetadataRepoLock) {
if (sMetadataRepo == null) {
@@ -136,7 +137,7 @@
}
@Override
- public void load(@NonNull EmojiCompat.MetadataRepoLoaderCallback loaderCallback) {
+ public void load(EmojiCompat.@NonNull MetadataRepoLoaderCallback loaderCallback) {
if (mMetadataRepo == null) {
try {
final Context context = ApplicationProvider.getApplicationContext();
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/util/Emoji.java b/emoji/emoji/src/androidTest/java/androidx/emoji/util/Emoji.java
index 9ade992..70bc15e 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/util/Emoji.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/util/Emoji.java
@@ -16,7 +16,7 @@
package androidx.emoji.util;
-import androidx.annotation.NonNull;
+import org.jspecify.annotations.NonNull;
public class Emoji {
@@ -86,7 +86,7 @@
private final int[] mCodepoints;
private final int mId;
- private EmojiMapping(@NonNull final int[] codepoints, final int id) {
+ private EmojiMapping(final int @NonNull [] codepoints, final int id) {
mCodepoints = codepoints;
mId = id;
}
diff --git a/emoji/emoji/src/main/java/androidx/emoji/text/EmojiCompat.java b/emoji/emoji/src/main/java/androidx/emoji/text/EmojiCompat.java
index df23ebc..acdab29 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/text/EmojiCompat.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/text/EmojiCompat.java
@@ -34,13 +34,14 @@
import androidx.annotation.GuardedBy;
import androidx.annotation.IntDef;
import androidx.annotation.IntRange;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.annotation.VisibleForTesting;
import androidx.collection.ArraySet;
import androidx.core.util.Preconditions;
+import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -263,7 +264,7 @@
*
* @see #init(Config)
*/
- private EmojiCompat(@NonNull final Config config) {
+ private EmojiCompat(final @NonNull Config config) {
mInitLock = new ReentrantReadWriteLock();
mLoadState = LOAD_STATE_DEFAULT;
mReplaceAll = config.mReplaceAll;
@@ -293,7 +294,7 @@
* @see EmojiCompat.Config
*/
@SuppressWarnings("GuardedBy")
- public static EmojiCompat init(@NonNull final Config config) {
+ public static EmojiCompat init(final @NonNull Config config) {
if (sInstance == null) {
synchronized (sInstanceLock) {
if (sInstance == null) {
@@ -312,7 +313,7 @@
@SuppressWarnings("GuardedBy")
@RestrictTo(LIBRARY_GROUP_PREFIX)
@VisibleForTesting
- public static EmojiCompat reset(@NonNull final Config config) {
+ public static EmojiCompat reset(final @NonNull Config config) {
synchronized (sInstanceLock) {
sInstance = new EmojiCompat(config);
}
@@ -412,7 +413,7 @@
}
@SuppressWarnings("WeakerAccess") /* synthetic access */
- void onMetadataLoadFailed(@Nullable final Throwable throwable) {
+ void onMetadataLoadFailed(final @Nullable Throwable throwable) {
final Collection<InitCallback> initCallbacks = new ArrayList<>();
mInitLock.writeLock().lock();
try {
@@ -527,7 +528,7 @@
*
* @return {@code true} if an {@link EmojiSpan} is deleted
*/
- public static boolean handleOnKeyDown(@NonNull final Editable editable, final int keyCode,
+ public static boolean handleOnKeyDown(final @NonNull Editable editable, final int keyCode,
final KeyEvent event) {
return EmojiProcessor.handleOnKeyDown(editable, keyCode, event);
}
@@ -551,7 +552,7 @@
* @return {@code true} if an {@link EmojiSpan} is deleted
*/
public static boolean handleDeleteSurroundingText(
- @NonNull final InputConnection inputConnection, @NonNull final Editable editable,
+ final @NonNull InputConnection inputConnection, final @NonNull Editable editable,
@IntRange(from = 0) final int beforeLength, @IntRange(from = 0) final int afterLength,
final boolean inCodePoints) {
return EmojiProcessor.handleDeleteSurroundingText(inputConnection, editable,
@@ -568,7 +569,7 @@
*
* @throws IllegalStateException if not initialized yet
*/
- public boolean hasEmojiGlyph(@NonNull final CharSequence sequence) {
+ public boolean hasEmojiGlyph(final @NonNull CharSequence sequence) {
Preconditions.checkState(isInitialized(), "Not initialized yet");
Preconditions.checkNotNull(sequence, "sequence cannot be null");
return mHelper.hasEmojiGlyph(sequence);
@@ -586,7 +587,7 @@
*
* @throws IllegalStateException if not initialized yet
*/
- public boolean hasEmojiGlyph(@NonNull final CharSequence sequence,
+ public boolean hasEmojiGlyph(final @NonNull CharSequence sequence,
@IntRange(from = 0) final int metadataVersion) {
Preconditions.checkState(isInitialized(), "Not initialized yet");
Preconditions.checkNotNull(sequence, "sequence cannot be null");
@@ -604,7 +605,7 @@
* @see #process(CharSequence, int, int)
*/
@CheckResult
- public CharSequence process(@NonNull final CharSequence charSequence) {
+ public CharSequence process(final @NonNull CharSequence charSequence) {
// since charSequence might be null here we have to check it. Passing through here to the
// main function so that it can do all the checks including isInitialized. It will also
// be the main point that decides what to return.
@@ -640,7 +641,7 @@
* {@code end > charSequence.length()}
*/
@CheckResult
- public CharSequence process(@NonNull final CharSequence charSequence,
+ public CharSequence process(final @NonNull CharSequence charSequence,
@IntRange(from = 0) final int start, @IntRange(from = 0) final int end) {
return process(charSequence, start, end, EMOJI_COUNT_UNLIMITED);
}
@@ -675,7 +676,7 @@
* {@code maxEmojiCount < 0}
*/
@CheckResult
- public CharSequence process(@NonNull final CharSequence charSequence,
+ public CharSequence process(final @NonNull CharSequence charSequence,
@IntRange(from = 0) final int start, @IntRange(from = 0) final int end,
@IntRange(from = 0) final int maxEmojiCount) {
return process(charSequence, start, end, maxEmojiCount, REPLACE_STRATEGY_DEFAULT);
@@ -715,7 +716,7 @@
* {@code maxEmojiCount < 0}
*/
@CheckResult
- public CharSequence process(@NonNull final CharSequence charSequence,
+ public CharSequence process(final @NonNull CharSequence charSequence,
@IntRange(from = 0) final int start, @IntRange(from = 0) final int end,
@IntRange(from = 0) final int maxEmojiCount, @ReplaceStrategy int replaceStrategy) {
Preconditions.checkState(isInitialized(), "Not initialized yet");
@@ -764,8 +765,7 @@
*
* @throws IllegalStateException if not initialized yet
*/
- @NonNull
- public String getAssetSignature() {
+ public @NonNull String getAssetSignature() {
Preconditions.checkState(isInitialized(), "Not initialized yet");
return mHelper.getAssetSignature();
}
@@ -788,7 +788,7 @@
*
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
- public void updateEditorInfoAttrs(@NonNull final EditorInfo outAttrs) {
+ public void updateEditorInfoAttrs(final @NonNull EditorInfo outAttrs) {
//noinspection ConstantConditions
if (!isInitialized() || outAttrs == null) {
return;
@@ -812,7 +812,7 @@
*
* @return EmojiSpan instance
*/
- EmojiSpan createSpan(@NonNull final EmojiMetadata metadata) {
+ EmojiSpan createSpan(final @NonNull EmojiMetadata metadata) {
return new TypefaceEmojiSpan(metadata);
}
}
@@ -953,7 +953,7 @@
*
* @param metadataLoader MetadataRepoLoader instance, cannot be {@code null}
*/
- protected Config(@NonNull final MetadataRepoLoader metadataLoader) {
+ protected Config(final @NonNull MetadataRepoLoader metadataLoader) {
Preconditions.checkNotNull(metadataLoader, "metadataLoader cannot be null.");
mMetadataLoader = metadataLoader;
}
@@ -1042,7 +1042,7 @@
* be used instead.
*/
public Config setUseEmojiAsDefaultStyle(final boolean useEmojiAsDefaultStyle,
- @Nullable final List<Integer> emojiAsDefaultStyleExceptions) {
+ final @Nullable List<Integer> emojiAsDefaultStyleExceptions) {
mUseEmojiAsDefaultStyle = useEmojiAsDefaultStyle;
if (mUseEmojiAsDefaultStyle && emojiAsDefaultStyleExceptions != null) {
mEmojiAsDefaultStyleExceptions = new int[emojiAsDefaultStyleExceptions.size()];
@@ -1128,8 +1128,7 @@
*
* @param glyphChecker {@link GlyphChecker} instance to be used.
*/
- @NonNull
- public Config setGlyphChecker(@NonNull GlyphChecker glyphChecker) {
+ public @NonNull Config setGlyphChecker(@NonNull GlyphChecker glyphChecker) {
Preconditions.checkNotNull(glyphChecker, "GlyphChecker cannot be null");
mGlyphChecker = glyphChecker;
return this;
@@ -1152,20 +1151,20 @@
private final int mLoadState;
@SuppressWarnings("ArraysAsListWithZeroOrOneArgument")
- ListenerDispatcher(@NonNull final InitCallback initCallback,
+ ListenerDispatcher(final @NonNull InitCallback initCallback,
@LoadState final int loadState) {
this(Arrays.asList(Preconditions.checkNotNull(initCallback,
"initCallback cannot be null")), loadState, null);
}
- ListenerDispatcher(@NonNull final Collection<InitCallback> initCallbacks,
+ ListenerDispatcher(final @NonNull Collection<InitCallback> initCallbacks,
@LoadState final int loadState) {
this(initCallbacks, loadState, null);
}
- ListenerDispatcher(@NonNull final Collection<InitCallback> initCallbacks,
+ ListenerDispatcher(final @NonNull Collection<InitCallback> initCallbacks,
@LoadState final int loadState,
- @Nullable final Throwable throwable) {
+ final @Nullable Throwable throwable) {
Preconditions.checkNotNull(initCallbacks, "initCallbacks cannot be null");
mInitCallbacks = new ArrayList<>(initCallbacks);
mLoadState = loadState;
@@ -1228,7 +1227,7 @@
}
}
- void onMetadataLoadSuccess(@NonNull final MetadataRepo metadataRepo) {
+ void onMetadataLoadSuccess(final @NonNull MetadataRepo metadataRepo) {
//noinspection ConstantConditions
if (metadataRepo == null) {
mEmojiCompat.onMetadataLoadFailed(
diff --git a/emoji/emoji/src/main/java/androidx/emoji/text/EmojiMetadata.java b/emoji/emoji/src/main/java/androidx/emoji/text/EmojiMetadata.java
index 4bbe1ad..0a2103f 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/text/EmojiMetadata.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/text/EmojiMetadata.java
@@ -24,11 +24,12 @@
import androidx.annotation.AnyThread;
import androidx.annotation.IntDef;
import androidx.annotation.IntRange;
-import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
import androidx.text.emoji.flatbuffer.MetadataItem;
import androidx.text.emoji.flatbuffer.MetadataList;
+import org.jspecify.annotations.NonNull;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -83,7 +84,7 @@
@HasGlyph
private volatile int mHasGlyph = HAS_GLYPH_UNKNOWN;
- EmojiMetadata(@NonNull final MetadataRepo metadataRepo, @IntRange(from = 0) final int index) {
+ EmojiMetadata(final @NonNull MetadataRepo metadataRepo, @IntRange(from = 0) final int index) {
mMetadataRepo = metadataRepo;
mIndex = index;
}
@@ -97,8 +98,8 @@
* @param y y-coordinate of the baseline of the emoji being drawn
* @param paint Paint used for the text (e.g. color, size, style)
*/
- public void draw(@NonNull final Canvas canvas, final float x, final float y,
- @NonNull final Paint paint) {
+ public void draw(final @NonNull Canvas canvas, final float x, final float y,
+ final @NonNull Paint paint) {
final Typeface typeface = mMetadataRepo.getTypeface();
final Typeface oldTypeface = paint.getTypeface();
paint.setTypeface(typeface);
diff --git a/emoji/emoji/src/main/java/androidx/emoji/text/EmojiProcessor.java b/emoji/emoji/src/main/java/androidx/emoji/text/EmojiProcessor.java
index d2b5877..f309b8b 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/text/EmojiProcessor.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/text/EmojiProcessor.java
@@ -32,12 +32,13 @@
import androidx.annotation.AnyThread;
import androidx.annotation.IntDef;
import androidx.annotation.IntRange;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.core.graphics.PaintCompat;
import androidx.emoji.widget.SpannableBuilder;
+import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
@@ -101,11 +102,11 @@
private final int[] mEmojiAsDefaultStyleExceptions;
EmojiProcessor(
- @NonNull final MetadataRepo metadataRepo,
- @NonNull final EmojiCompat.SpanFactory spanFactory,
- @NonNull final EmojiCompat.GlyphChecker glyphChecker,
+ final @NonNull MetadataRepo metadataRepo,
+ final EmojiCompat.@NonNull SpanFactory spanFactory,
+ final EmojiCompat.@NonNull GlyphChecker glyphChecker,
final boolean useEmojiAsDefaultStyle,
- @Nullable final int[] emojiAsDefaultStyleExceptions
+ final int @Nullable [] emojiAsDefaultStyleExceptions
) {
mSpanFactory = spanFactory;
mMetadataRepo = metadataRepo;
@@ -114,7 +115,7 @@
mEmojiAsDefaultStyleExceptions = emojiAsDefaultStyleExceptions;
}
- EmojiMetadata getEmojiMetadata(@NonNull final CharSequence charSequence) {
+ EmojiMetadata getEmojiMetadata(final @NonNull CharSequence charSequence) {
final ProcessorSm sm = new ProcessorSm(mMetadataRepo.getRootNode(),
mUseEmojiAsDefaultStyle, mEmojiAsDefaultStyleExceptions);
final int end = charSequence.length();
@@ -157,7 +158,7 @@
* than or equal to {@code 0}
* @param replaceAll whether to replace all emoji with {@link EmojiSpan}s
*/
- CharSequence process(@NonNull final CharSequence charSequence, @IntRange(from = 0) int start,
+ CharSequence process(final @NonNull CharSequence charSequence, @IntRange(from = 0) int start,
@IntRange(from = 0) int end, @IntRange(from = 0) int maxEmojiCount,
final boolean replaceAll) {
final boolean isSpannableBuilder = charSequence instanceof SpannableBuilder;
@@ -294,7 +295,7 @@
*
* @return {@code true} if an {@link EmojiSpan} is deleted
*/
- static boolean handleOnKeyDown(@NonNull final Editable editable, final int keyCode,
+ static boolean handleOnKeyDown(final @NonNull Editable editable, final int keyCode,
final KeyEvent event) {
final boolean handled;
switch (keyCode) {
@@ -364,8 +365,8 @@
*
* @return {@code true} if an {@link EmojiSpan} is deleted
*/
- static boolean handleDeleteSurroundingText(@NonNull final InputConnection inputConnection,
- @NonNull final Editable editable, @IntRange(from = 0) final int beforeLength,
+ static boolean handleDeleteSurroundingText(final @NonNull InputConnection inputConnection,
+ final @NonNull Editable editable, @IntRange(from = 0) final int beforeLength,
@IntRange(from = 0) final int afterLength, final boolean inCodePoints) {
//noinspection ConstantConditions
if (editable == null || inputConnection == null) {
@@ -432,7 +433,7 @@
return !KeyEvent.metaStateHasNoModifiers(event.getMetaState());
}
- private void addEmoji(@NonNull final Spannable spannable, final EmojiMetadata metadata,
+ private void addEmoji(final @NonNull Spannable spannable, final EmojiMetadata metadata,
final int start, final int end) {
final EmojiSpan span = mSpanFactory.createSpan(metadata);
spannable.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
diff --git a/emoji/emoji/src/main/java/androidx/emoji/text/EmojiSpan.java b/emoji/emoji/src/main/java/androidx/emoji/text/EmojiSpan.java
index 52d37db..98d783d 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/text/EmojiSpan.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/text/EmojiSpan.java
@@ -20,11 +20,12 @@
import android.graphics.Paint;
import android.text.style.ReplacementSpan;
-import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
import androidx.annotation.VisibleForTesting;
import androidx.core.util.Preconditions;
+import org.jspecify.annotations.NonNull;
+
/**
* Base span class for the emoji replacement. When an emoji is found and needs to be replaced in a
* CharSequence, an instance of this class is added to the CharSequence.
@@ -65,13 +66,13 @@
*
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
- EmojiSpan(@NonNull final EmojiMetadata metadata) {
+ EmojiSpan(final @NonNull EmojiMetadata metadata) {
Preconditions.checkNotNull(metadata, "metadata cannot be null");
mMetadata = metadata;
}
@Override
- public int getSize(@NonNull final Paint paint, final CharSequence text, final int start,
+ public int getSize(final @NonNull Paint paint, final CharSequence text, final int start,
final int end, final Paint.FontMetricsInt fm) {
paint.getFontMetricsInt(mTmpFontMetrics);
final int fontHeight = Math.abs(mTmpFontMetrics.descent - mTmpFontMetrics.ascent);
diff --git a/emoji/emoji/src/main/java/androidx/emoji/text/FontRequestEmojiCompatConfig.java b/emoji/emoji/src/main/java/androidx/emoji/text/FontRequestEmojiCompatConfig.java
index 09bb45d..f0f6800 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/text/FontRequestEmojiCompatConfig.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/text/FontRequestEmojiCompatConfig.java
@@ -27,8 +27,6 @@
import android.os.SystemClock;
import androidx.annotation.GuardedBy;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.core.graphics.TypefaceCompatUtil;
import androidx.core.provider.FontRequest;
@@ -36,6 +34,9 @@
import androidx.core.provider.FontsContractCompat.FontFamilyResult;
import androidx.core.util.Preconditions;
+import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
+
import java.nio.ByteBuffer;
/**
@@ -201,7 +202,7 @@
}
@Override
- public void load(@NonNull final EmojiCompat.MetadataRepoLoaderCallback loaderCallback) {
+ public void load(final EmojiCompat.@NonNull MetadataRepoLoaderCallback loaderCallback) {
Preconditions.checkNotNull(loaderCallback, "LoaderCallback cannot be null");
synchronized (mLock) {
if (mHandler == null) {
@@ -333,7 +334,7 @@
/** Calls FontsContractCompat.buildTypeface. */
public Typeface buildTypeface(@NonNull Context context,
- @NonNull FontsContractCompat.FontInfo font) throws NameNotFoundException {
+ FontsContractCompat.@NonNull FontInfo font) throws NameNotFoundException {
return FontsContractCompat.buildTypeface(context, null /* cancellation signal */,
new FontsContractCompat.FontInfo[] { font });
}
diff --git a/emoji/emoji/src/main/java/androidx/emoji/text/MetadataRepo.java b/emoji/emoji/src/main/java/androidx/emoji/text/MetadataRepo.java
index 23e474c..b363e78 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/text/MetadataRepo.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/text/MetadataRepo.java
@@ -22,12 +22,13 @@
import android.util.SparseArray;
import androidx.annotation.AnyThread;
-import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
import androidx.annotation.VisibleForTesting;
import androidx.core.util.Preconditions;
import androidx.text.emoji.flatbuffer.MetadataList;
+import org.jspecify.annotations.NonNull;
+
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
@@ -81,8 +82,8 @@
* @param typeface Typeface to be used to render emojis
* @param metadataList MetadataList that contains the emoji metadata
*/
- private MetadataRepo(@NonNull final Typeface typeface,
- @NonNull final MetadataList metadataList) {
+ private MetadataRepo(final @NonNull Typeface typeface,
+ final @NonNull MetadataList metadataList) {
mTypeface = typeface;
mMetadataList = metadataList;
mRootNode = new Node(DEFAULT_ROOT_SIZE);
@@ -97,8 +98,8 @@
* @param typeface Typeface to be used to render emojis
* @param inputStream InputStream to read emoji metadata from
*/
- public static MetadataRepo create(@NonNull final Typeface typeface,
- @NonNull final InputStream inputStream) throws IOException {
+ public static MetadataRepo create(final @NonNull Typeface typeface,
+ final @NonNull InputStream inputStream) throws IOException {
return new MetadataRepo(typeface, MetadataListReader.read(inputStream));
}
@@ -109,8 +110,8 @@
* @param typeface Typeface to be used to render emojis
* @param byteBuffer ByteBuffer to read emoji metadata from
*/
- public static MetadataRepo create(@NonNull final Typeface typeface,
- @NonNull final ByteBuffer byteBuffer) throws IOException {
+ public static MetadataRepo create(final @NonNull Typeface typeface,
+ final @NonNull ByteBuffer byteBuffer) throws IOException {
return new MetadataRepo(typeface, MetadataListReader.read(byteBuffer));
}
@@ -121,7 +122,7 @@
* @param assetPath asset manager path of the file that the Typeface and metadata will be
* created from
*/
- public static MetadataRepo create(@NonNull final AssetManager assetManager,
+ public static MetadataRepo create(final @NonNull AssetManager assetManager,
final String assetPath) throws IOException {
final Typeface typeface = Typeface.createFromAsset(assetManager, assetPath);
return new MetadataRepo(typeface, MetadataListReader.read(assetManager, assetPath));
@@ -183,7 +184,7 @@
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
@VisibleForTesting
- void put(@NonNull final EmojiMetadata data) {
+ void put(final @NonNull EmojiMetadata data) {
Preconditions.checkNotNull(data, "emoji metadata cannot be null");
Preconditions.checkArgument(data.getCodepointsLength() > 0,
"invalid metadata codepoint length");
@@ -219,7 +220,7 @@
}
@SuppressWarnings("WeakerAccess") /* synthetic access */
- void put(@NonNull final EmojiMetadata data, final int start, final int end) {
+ void put(final @NonNull EmojiMetadata data, final int start, final int end) {
Node node = get(data.getCodepointAt(start));
if (node == null) {
node = new Node();
diff --git a/emoji/emoji/src/main/java/androidx/emoji/text/TypefaceEmojiSpan.java b/emoji/emoji/src/main/java/androidx/emoji/text/TypefaceEmojiSpan.java
index 78206a2..dcfd8da 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/text/TypefaceEmojiSpan.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/text/TypefaceEmojiSpan.java
@@ -22,9 +22,10 @@
import android.text.TextPaint;
import androidx.annotation.IntRange;
-import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
+import org.jspecify.annotations.NonNull;
+
/**
* EmojiSpan subclass used to render emojis using Typeface.
*
@@ -47,9 +48,9 @@
}
@Override
- public void draw(@NonNull final Canvas canvas, final CharSequence text,
+ public void draw(final @NonNull Canvas canvas, final CharSequence text,
@IntRange(from = 0) final int start, @IntRange(from = 0) final int end, final float x,
- final int top, final int y, final int bottom, @NonNull final Paint paint) {
+ final int top, final int y, final int bottom, final @NonNull Paint paint) {
if (EmojiCompat.get().isEmojiSpanIndicatorEnabled()) {
canvas.drawRect(x, top , x + getWidth(), bottom, getDebugPaint());
}
diff --git a/emoji/emoji/src/main/java/androidx/emoji/widget/EditTextAttributeHelper.java b/emoji/emoji/src/main/java/androidx/emoji/widget/EditTextAttributeHelper.java
index eb90512..780e6fe 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/widget/EditTextAttributeHelper.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/widget/EditTextAttributeHelper.java
@@ -23,10 +23,11 @@
import android.util.AttributeSet;
import android.view.View;
-import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
import androidx.emoji.R;
+import org.jspecify.annotations.NonNull;
+
/**
* Helper class to parse EmojiCompat EditText attributes.
*
diff --git a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiEditText.java b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiEditText.java
index d8670259..c8f7f84 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiEditText.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiEditText.java
@@ -25,11 +25,12 @@
import android.widget.EditText;
import androidx.annotation.IntRange;
-import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.widget.TextViewCompat;
import androidx.emoji.text.EmojiCompat;
+import org.jspecify.annotations.Nullable;
+
/**
* EditText widget enhanced with emoji capability by using {@link EmojiEditTextHelper}. When used
* on devices running API 18 or below, this widget acts as a regular {@link EditText}.
diff --git a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiEditTextHelper.java b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiEditTextHelper.java
index cd555ea..15ac6b0 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiEditTextHelper.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiEditTextHelper.java
@@ -24,13 +24,14 @@
import android.widget.TextView;
import androidx.annotation.IntRange;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.core.util.Preconditions;
import androidx.emoji.text.EmojiCompat;
import androidx.emoji.text.EmojiSpan;
+import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
+
/**
* Utility class to enhance custom EditText widgets with {@link EmojiCompat}.
* <p/>
@@ -78,7 +79,7 @@
*
* @param editText EditText instance
*/
- public EmojiEditTextHelper(@NonNull final EditText editText) {
+ public EmojiEditTextHelper(final @NonNull EditText editText) {
Preconditions.checkNotNull(editText, "editText cannot be null");
mEditText = editText;
mTextWatcher = new EmojiTextWatcher(mEditText);
@@ -124,8 +125,7 @@
*
* @return a new KeyListener instance that wraps {@code keyListener}.
*/
- @NonNull
- public KeyListener getKeyListener(@NonNull final KeyListener keyListener) {
+ public @NonNull KeyListener getKeyListener(final @NonNull KeyListener keyListener) {
Preconditions.checkNotNull(keyListener, "keyListener cannot be null");
if (keyListener instanceof EmojiKeyListener) {
return keyListener;
@@ -145,9 +145,8 @@
*
* @return a new InputConnection instance that wraps {@code inputConnection}
*/
- @Nullable
- public InputConnection onCreateInputConnection(@Nullable final InputConnection inputConnection,
- @NonNull final EditorInfo outAttrs) {
+ public @Nullable InputConnection onCreateInputConnection(
+ final @Nullable InputConnection inputConnection, final @NonNull EditorInfo outAttrs) {
if (inputConnection == null) return null;
if (inputConnection instanceof EmojiInputConnection) {
return inputConnection;
diff --git a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiEditableFactory.java b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiEditableFactory.java
index e7f12ef..b51d635 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiEditableFactory.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiEditableFactory.java
@@ -19,8 +19,9 @@
import android.text.Editable;
import androidx.annotation.GuardedBy;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
+
+import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
/**
* EditableFactory used to improve editing operations on an EditText.
@@ -44,7 +45,7 @@
@GuardedBy("sInstanceLock")
private static volatile Editable.Factory sInstance;
- @Nullable private static Class<?> sWatcherClass;
+ private static @Nullable Class<?> sWatcherClass;
@SuppressLint("PrivateApi")
private EmojiEditableFactory() {
@@ -69,7 +70,7 @@
}
@Override
- public Editable newEditable(@NonNull final CharSequence source) {
+ public Editable newEditable(final @NonNull CharSequence source) {
if (sWatcherClass != null) {
return SpannableBuilder.create(sWatcherClass, source);
}
diff --git a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiExtractEditText.java b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiExtractEditText.java
index 57a9cea..42acd49 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiExtractEditText.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiExtractEditText.java
@@ -29,13 +29,14 @@
import android.widget.TextView;
import androidx.annotation.IntRange;
-import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
import androidx.core.widget.TextViewCompat;
import androidx.emoji.text.EmojiCompat;
import androidx.emoji.text.EmojiSpan;
+import org.jspecify.annotations.Nullable;
+
/**
* ExtractEditText widget enhanced with emoji capability by using {@link EmojiEditTextHelper}.
* When used on devices running API 18 or below, this widget acts as a {@link ExtractEditText} and
diff --git a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiExtractTextLayout.java b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiExtractTextLayout.java
index 38f5d8c..2741575 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiExtractTextLayout.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiExtractTextLayout.java
@@ -29,14 +29,15 @@
import android.view.inputmethod.InputConnection;
import android.widget.LinearLayout;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.view.ViewCompat;
import androidx.emoji.R;
import androidx.emoji.text.EmojiCompat;
import androidx.emoji.text.EmojiSpan;
+import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
+
/**
* Layout that contains emoji compatibility enhanced ExtractEditText. Should be used by
* {@link InputMethodService} implementations.
diff --git a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiInputConnection.java b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiInputConnection.java
index 237dc72..f17c4ea 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiInputConnection.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiInputConnection.java
@@ -23,10 +23,11 @@
import android.view.inputmethod.InputConnectionWrapper;
import android.widget.TextView;
-import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
import androidx.emoji.text.EmojiCompat;
+import org.jspecify.annotations.NonNull;
+
/**
* InputConnectionWrapper for EditText delete operations. Keyboard does not have knowledge about
* emojis and therefore might send commands to delete a part of the emoji sequence which creates
@@ -40,9 +41,9 @@
private final TextView mTextView;
EmojiInputConnection(
- @NonNull final TextView textView,
- @NonNull final InputConnection inputConnection,
- @NonNull final EditorInfo outAttrs) {
+ final @NonNull TextView textView,
+ final @NonNull InputConnection inputConnection,
+ final @NonNull EditorInfo outAttrs) {
super(inputConnection, false);
mTextView = textView;
EmojiCompat.get().updateEditorInfoAttrs(outAttrs);
diff --git a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiInputFilter.java b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiInputFilter.java
index e1adc9c..17d3dff 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiInputFilter.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiInputFilter.java
@@ -24,11 +24,12 @@
import android.text.Spanned;
import android.widget.TextView;
-import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
import androidx.emoji.text.EmojiCompat;
import androidx.emoji.text.EmojiCompat.InitCallback;
+import org.jspecify.annotations.NonNull;
+
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
@@ -45,7 +46,7 @@
private final TextView mTextView;
private InitCallback mInitCallback;
- EmojiInputFilter(@NonNull final TextView textView) {
+ EmojiInputFilter(final @NonNull TextView textView) {
mTextView = textView;
}
diff --git a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiTextViewHelper.java b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiTextViewHelper.java
index d061388..8986500 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiTextViewHelper.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiTextViewHelper.java
@@ -20,11 +20,12 @@
import android.text.method.TransformationMethod;
import android.widget.TextView;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.core.util.Preconditions;
import androidx.emoji.text.EmojiCompat;
+import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
+
/**
* Utility class to enhance custom TextView widgets with {@link EmojiCompat}.
* <pre>
@@ -93,8 +94,7 @@
* @return same copy if the array already contains EmojiCompat InputFilter. A new array copy if
* not.
*/
- @NonNull
- public InputFilter[] getFilters(@NonNull final InputFilter[] filters) {
+ public InputFilter @NonNull [] getFilters(final InputFilter @NonNull [] filters) {
return mHelper.getFilters(filters);
}
@@ -105,8 +105,7 @@
*
* @param transformationMethod instance to be wrapped
*/
- @Nullable
- public TransformationMethod wrapTransformationMethod(
+ public @Nullable TransformationMethod wrapTransformationMethod(
@Nullable TransformationMethod transformationMethod) {
return mHelper.wrapTransformationMethod(transformationMethod);
}
@@ -137,7 +136,7 @@
}
}
- InputFilter[] getFilters(@NonNull final InputFilter[] filters) {
+ InputFilter[] getFilters(final InputFilter @NonNull [] filters) {
final int count = filters.length;
for (int i = 0; i < count; i++) {
if (filters[i] instanceof EmojiInputFilter) {
diff --git a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiTransformationMethod.java b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiTransformationMethod.java
index 8aa071a..840a784 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiTransformationMethod.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiTransformationMethod.java
@@ -21,11 +21,12 @@
import android.text.method.TransformationMethod;
import android.view.View;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.emoji.text.EmojiCompat;
+import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
+
/**
* TransformationMethod wrapper in order to update transformed text with emojis.
*
@@ -39,7 +40,7 @@
}
@Override
- public CharSequence getTransformation(@Nullable CharSequence source, @NonNull final View view) {
+ public CharSequence getTransformation(@Nullable CharSequence source, final @NonNull View view) {
if (view.isInEditMode()) {
return source;
}
diff --git a/emoji/emoji/src/main/java/androidx/emoji/widget/SpannableBuilder.java b/emoji/emoji/src/main/java/androidx/emoji/widget/SpannableBuilder.java
index 5b8eca8..c7137f9 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/widget/SpannableBuilder.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/widget/SpannableBuilder.java
@@ -23,12 +23,13 @@
import android.text.SpannableStringBuilder;
import android.text.TextWatcher;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.core.util.Preconditions;
import androidx.emoji.text.EmojiSpan;
+import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
+
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;