From eb9044949cc04a76d77535f440ee674f4259204d Mon Sep 17 00:00:00 2001 From: turbojax07 Date: Tue, 18 Nov 2025 00:39:51 -0500 Subject: [PATCH 01/10] Removing BossBarViewer and replacing its references with Audience --- .../kyori/adventure/audience/Audience.java | 14 ++++++- .../net/kyori/adventure/bossbar/BossBar.java | 2 +- .../kyori/adventure/bossbar/BossBarImpl.java | 3 +- .../bossbar/BossBarImplementation.java | 3 +- .../adventure/bossbar/BossBarViewer.java | 42 ------------------- 5 files changed, 17 insertions(+), 47 deletions(-) delete mode 100644 api/src/main/java/net/kyori/adventure/bossbar/BossBarViewer.java diff --git a/api/src/main/java/net/kyori/adventure/audience/Audience.java b/api/src/main/java/net/kyori/adventure/audience/Audience.java index 9efd225a55..a3e73f4eb3 100644 --- a/api/src/main/java/net/kyori/adventure/audience/Audience.java +++ b/api/src/main/java/net/kyori/adventure/audience/Audience.java @@ -32,8 +32,8 @@ import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Collector; +import org.jetbrains.annotations.UnmodifiableView; import net.kyori.adventure.bossbar.BossBar; -import net.kyori.adventure.bossbar.BossBarViewer; import net.kyori.adventure.chat.ChatType; import net.kyori.adventure.chat.SignedMessage; import net.kyori.adventure.dialog.DialogLike; @@ -95,7 +95,6 @@ * and any new methods will be stubbed by default.

* * @see ForwardingAudience - * @see BossBarViewer * @since 4.0.0 */ public interface Audience extends Pointered { @@ -441,6 +440,17 @@ default void showBossBar(final BossBar bar) { default void hideBossBar(final BossBar bar) { } + /** + * Gets an unmodifiable view of all known currently active bossbars. + * + * @return an unmodifiable view of all known currently active bossbars + * @since 4.14.0 + */ + @UnmodifiableView + default Iterable activeBossBars() { + return List.of(); + } + /** * Plays a sound at the location of the recipient of the sound. * diff --git a/api/src/main/java/net/kyori/adventure/bossbar/BossBar.java b/api/src/main/java/net/kyori/adventure/bossbar/BossBar.java index 08b8da552d..70e704a4dd 100644 --- a/api/src/main/java/net/kyori/adventure/bossbar/BossBar.java +++ b/api/src/main/java/net/kyori/adventure/bossbar/BossBar.java @@ -335,7 +335,7 @@ default BossBar name(final ComponentLike name) { * @since 4.14.0 */ @UnmodifiableView - Iterable viewers(); + Iterable viewers(); /** * Show this bossbar to {@code viewer}. diff --git a/api/src/main/java/net/kyori/adventure/bossbar/BossBarImpl.java b/api/src/main/java/net/kyori/adventure/bossbar/BossBarImpl.java index c044f35b52..b1966a882d 100644 --- a/api/src/main/java/net/kyori/adventure/bossbar/BossBarImpl.java +++ b/api/src/main/java/net/kyori/adventure/bossbar/BossBarImpl.java @@ -32,6 +32,7 @@ import java.util.function.BiConsumer; import java.util.function.BiPredicate; import java.util.function.Consumer; +import net.kyori.adventure.audience.Audience; import net.kyori.adventure.text.Component; import net.kyori.adventure.util.Services; import org.jspecify.annotations.Nullable; @@ -261,7 +262,7 @@ public BossBar removeListener(final Listener listener) { } @Override - public Iterable viewers() { + public Iterable viewers() { if (this.implementation != null) { return this.implementation.viewers(); } diff --git a/api/src/main/java/net/kyori/adventure/bossbar/BossBarImplementation.java b/api/src/main/java/net/kyori/adventure/bossbar/BossBarImplementation.java index 1362dc3502..b1b9c9b352 100644 --- a/api/src/main/java/net/kyori/adventure/bossbar/BossBarImplementation.java +++ b/api/src/main/java/net/kyori/adventure/bossbar/BossBarImplementation.java @@ -25,6 +25,7 @@ import java.util.List; import org.jetbrains.annotations.ApiStatus; +import net.kyori.adventure.audience.Audience; /** * {@link BossBar} internal implementation. @@ -54,7 +55,7 @@ static I get(final BossBar bar, final Class * @since 4.14.0 */ @ApiStatus.Internal - default Iterable viewers() { + default Iterable viewers() { return List.of(); } diff --git a/api/src/main/java/net/kyori/adventure/bossbar/BossBarViewer.java b/api/src/main/java/net/kyori/adventure/bossbar/BossBarViewer.java deleted file mode 100644 index dc81866cb0..0000000000 --- a/api/src/main/java/net/kyori/adventure/bossbar/BossBarViewer.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of adventure, licensed under the MIT License. - * - * Copyright (c) 2017-2025 KyoriPowered - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package net.kyori.adventure.bossbar; - -import org.jetbrains.annotations.UnmodifiableView; - -/** - * Something that can view a {@link BossBar}. - * - * @since 4.14.0 - */ -public interface BossBarViewer { - /** - * Gets an unmodifiable view of all known currently active bossbars. - * - * @return an unmodifiable view of all known currently active bossbars - * @since 4.14.0 - */ - @UnmodifiableView - Iterable activeBossBars(); -} From b3a0fb7df5f7c48061c0b1c414477efa09c96415 Mon Sep 17 00:00:00 2001 From: turbojax07 Date: Tue, 18 Nov 2025 00:50:25 -0500 Subject: [PATCH 02/10] Adding activeBossBars overrides to ForwardingAudience.java --- .../audience/ForwardingAudience.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java b/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java index cf8dc5a546..4fce60c0d6 100644 --- a/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java +++ b/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java @@ -25,8 +25,10 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.UUID; import java.util.function.Consumer; import java.util.function.Predicate; @@ -46,6 +48,7 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.UnknownNullability; +import org.jetbrains.annotations.UnmodifiableView; import org.jspecify.annotations.Nullable; /** @@ -162,6 +165,18 @@ default void hideBossBar(final BossBar bar) { for (final Audience audience : this.audiences()) audience.hideBossBar(bar); } + @Override + default @UnmodifiableView Iterable activeBossBars() { + Set bossBars = new HashSet<>(); + for (final Audience audience : this.audiences()) { + for (BossBar bb : audience.activeBossBars()) { + bossBars.add(bb); + } + } + + return bossBars; + } + @Override default void playSound(final Sound sound) { for (final Audience audience : this.audiences()) audience.playSound(sound); @@ -343,6 +358,11 @@ default void hideBossBar(final BossBar bar) { this.audience().hideBossBar(bar); } + @Override + default @UnmodifiableView Iterable activeBossBars() { + return this.audience().activeBossBars(); + } + @Override default void playSound(final Sound sound) { this.audience().playSound(sound); From 936ccaaaa1c246aba4e6e03f37168144d194b051 Mon Sep 17 00:00:00 2001 From: turbojax07 Date: Wed, 7 Jan 2026 18:35:15 -0500 Subject: [PATCH 03/10] formatting --- .../main/java/net/kyori/adventure/audience/Audience.java | 2 +- .../net/kyori/adventure/audience/ForwardingAudience.java | 6 ++---- .../net/kyori/adventure/bossbar/BossBarImplementation.java | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/net/kyori/adventure/audience/Audience.java b/api/src/main/java/net/kyori/adventure/audience/Audience.java index a3e73f4eb3..aeb23ff1b7 100644 --- a/api/src/main/java/net/kyori/adventure/audience/Audience.java +++ b/api/src/main/java/net/kyori/adventure/audience/Audience.java @@ -32,7 +32,6 @@ import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Collector; -import org.jetbrains.annotations.UnmodifiableView; import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.chat.ChatType; import net.kyori.adventure.chat.SignedMessage; @@ -50,6 +49,7 @@ import net.kyori.adventure.text.ComponentLike; import net.kyori.adventure.title.Title; import net.kyori.adventure.title.TitlePart; +import org.jetbrains.annotations.UnmodifiableView; /** * A receiver of Minecraft media. diff --git a/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java b/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java index 4fce60c0d6..d2d3aa3d4f 100644 --- a/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java +++ b/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java @@ -169,9 +169,7 @@ default void hideBossBar(final BossBar bar) { default @UnmodifiableView Iterable activeBossBars() { Set bossBars = new HashSet<>(); for (final Audience audience : this.audiences()) { - for (BossBar bb : audience.activeBossBars()) { - bossBars.add(bb); - } + for (final BossBar bb : audience.activeBossBars()) bossBars.add(bb); } return bossBars; @@ -360,7 +358,7 @@ default void hideBossBar(final BossBar bar) { @Override default @UnmodifiableView Iterable activeBossBars() { - return this.audience().activeBossBars(); + return this.audience().activeBossBars(); } @Override diff --git a/api/src/main/java/net/kyori/adventure/bossbar/BossBarImplementation.java b/api/src/main/java/net/kyori/adventure/bossbar/BossBarImplementation.java index b1b9c9b352..9b6645fdf5 100644 --- a/api/src/main/java/net/kyori/adventure/bossbar/BossBarImplementation.java +++ b/api/src/main/java/net/kyori/adventure/bossbar/BossBarImplementation.java @@ -24,8 +24,8 @@ package net.kyori.adventure.bossbar; import java.util.List; -import org.jetbrains.annotations.ApiStatus; import net.kyori.adventure.audience.Audience; +import org.jetbrains.annotations.ApiStatus; /** * {@link BossBar} internal implementation. From 35a46d821c9fc9040f89d7f95c1638e00376ad26 Mon Sep 17 00:00:00 2001 From: turbojax07 Date: Wed, 7 Jan 2026 19:07:00 -0500 Subject: [PATCH 04/10] Fixing checkstyle error --- .../java/net/kyori/adventure/audience/ForwardingAudience.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java b/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java index d2d3aa3d4f..9451b06d48 100644 --- a/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java +++ b/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java @@ -167,7 +167,7 @@ default void hideBossBar(final BossBar bar) { @Override default @UnmodifiableView Iterable activeBossBars() { - Set bossBars = new HashSet<>(); + final Set bossBars = new HashSet<>(); for (final Audience audience : this.audiences()) { for (final BossBar bb : audience.activeBossBars()) bossBars.add(bb); } From 8fc9785bfe6a8b750b73d89ae6c56f65233dc692 Mon Sep 17 00:00:00 2001 From: Kieran Wallbanks Date: Wed, 25 Mar 2026 16:25:04 +0000 Subject: [PATCH 05/10] chore: Fix a bunch more build warnings --- .checkstyle/checkstyle.xml | 2 +- .../net/kyori/adventure/chat/ChatType.java | 1 + .../adventure/text/event/ClickEvent.java | 2 +- .../adventure/text/event/HoverEvent.java | 4 +-- .../kyori/adventure/text/format/Style.java | 5 ++-- .../TranslatableComponentRenderer.java | 1 + .../adventure/text/AbstractComponentTest.java | 1 + .../text/ComponentCompactingTest.java | 1 + .../adventure/text/ComponentIteratorTest.java | 16 ++++------- .../util/ComponentMessageThrowableTest.java | 1 - .../net/kyori/adventure/util/TicksTest.java | 1 + .../adventure.common-conventions.gradle.kts | 5 ++++ .../kyori/adventure/nbt/ByteBinaryTag.java | 1 + .../ComponentLoggingEventBuilderImpl.java | 4 +-- .../NoOpComponentLoggingEventBuilderImpl.java | 28 +++++++++---------- .../slf4j/WrappingComponentLoggerImpl.java | 1 + .../minimessage/internal/TagInternals.java | 4 +-- .../internal/parser/TokenParser.java | 9 +++--- .../text/minimessage/tag/StylingTagImpl.java | 1 + .../adventure/text/minimessage/tag/Tag.java | 4 ++- .../text/minimessage/tag/TagPattern.java | 14 ++++++++-- .../tag/standard/SequentialHeadTag.java | 3 +- .../tag/standard/TransitionTag.java | 1 + .../commons/ComponentTreeConstants.java | 16 ++++++----- .../gson/ComponentSerializerImpl.java | 4 +-- .../gson/GsonDataComponentValueImpl.java | 3 +- .../text/serializer/gson/StyleSerializer.java | 2 +- .../serializer/gson/TextColorSerializer.java | 4 +-- .../legacy/LegacyComponentSerializerImpl.java | 5 ++-- 29 files changed, 83 insertions(+), 61 deletions(-) diff --git a/.checkstyle/checkstyle.xml b/.checkstyle/checkstyle.xml index 8c6c3d03cc..b3b74e0406 100644 --- a/.checkstyle/checkstyle.xml +++ b/.checkstyle/checkstyle.xml @@ -42,7 +42,7 @@ - + diff --git a/api/src/main/java/net/kyori/adventure/chat/ChatType.java b/api/src/main/java/net/kyori/adventure/chat/ChatType.java index 134a00eb88..716760a9fe 100644 --- a/api/src/main/java/net/kyori/adventure/chat/ChatType.java +++ b/api/src/main/java/net/kyori/adventure/chat/ChatType.java @@ -38,6 +38,7 @@ * @since 4.12.0 * @sinceMinecraft 1.19 */ +@SuppressWarnings("ClassInitializationDeadlock") // It's fine. public interface ChatType { /** * A chat message from a player. diff --git a/api/src/main/java/net/kyori/adventure/text/event/ClickEvent.java b/api/src/main/java/net/kyori/adventure/text/event/ClickEvent.java index 5aaef7b35b..2e66f27580 100644 --- a/api/src/main/java/net/kyori/adventure/text/event/ClickEvent.java +++ b/api/src/main/java/net/kyori/adventure/text/event/ClickEvent.java @@ -284,7 +284,7 @@ public String toString() { * @param the payload type * @since 4.0.0 */ - @SuppressWarnings("StaticInitializerReferencesSubClass") // We have private subclasses and private constructors for them, so this is fine. + @SuppressWarnings({"StaticInitializerReferencesSubClass", "ClassInitializationDeadlock"}) // We have private subclasses and private constructors for them, so this is fine. public static sealed abstract class Action permits Action.ChangePage, Action.Custom, Action.ShowDialog, Action.TextCarrier { /** * Opens a url when clicked. diff --git a/api/src/main/java/net/kyori/adventure/text/event/HoverEvent.java b/api/src/main/java/net/kyori/adventure/text/event/HoverEvent.java index 174a95f9a0..b9a17a6982 100644 --- a/api/src/main/java/net/kyori/adventure/text/event/HoverEvent.java +++ b/api/src/main/java/net/kyori/adventure/text/event/HoverEvent.java @@ -399,7 +399,7 @@ public static ShowItem showItem(final Key item, final @Range(from = 0, to = Inte * @param nbt the nbt * @return a {@code ShowItem} * @since 4.14.0 - * @deprecated since 1.20.5 and replaced with data components + * @obsolete since 1.20.5 and replaced with data components */ @ApiStatus.Obsolete public static ShowItem showItem(final Keyed item, final @Range(from = 0, to = Integer.MAX_VALUE) int count, final @Nullable BinaryTagHolder nbt) { @@ -498,7 +498,7 @@ public ShowItem count(final @Range(from = 0, to = Integer.MAX_VALUE) int count) * @param nbt the nbt * @return a {@code ShowItem} * @since 4.0.0 - * @deprecated since 1.20.5 and replaced with data components + * @obsoleteSinceMinecraft 1.20.5 and replaced with data components */ @ApiStatus.Obsolete public ShowItem nbt(final @Nullable BinaryTagHolder nbt) { diff --git a/api/src/main/java/net/kyori/adventure/text/format/Style.java b/api/src/main/java/net/kyori/adventure/text/format/Style.java index 031c4b5224..1eb648be90 100644 --- a/api/src/main/java/net/kyori/adventure/text/format/Style.java +++ b/api/src/main/java/net/kyori/adventure/text/format/Style.java @@ -37,7 +37,6 @@ import net.kyori.adventure.util.Buildable; import net.kyori.adventure.util.MonkeyBars; import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.UnknownNullability; import org.jetbrains.annotations.Unmodifiable; import org.jspecify.annotations.Nullable; @@ -160,7 +159,8 @@ static Style style(final @Nullable TextColor color, final Set de * @return a style * @since 4.0.0 */ - static Style style(final @UnknownNullability StyleBuilderApplicable... applicables) { + @SuppressWarnings("overloads") // It's fine, it's not really correct. + static Style style(final @Nullable StyleBuilderApplicable... applicables) { final int length = applicables.length; if (length == 0) return empty(); final Builder builder = style(); @@ -548,6 +548,7 @@ default Style merge(final Style that, final Set merges) { * @return a builder * @since 4.0.0 */ + @Override Builder toBuilder(); /** diff --git a/api/src/main/java/net/kyori/adventure/text/renderer/TranslatableComponentRenderer.java b/api/src/main/java/net/kyori/adventure/text/renderer/TranslatableComponentRenderer.java index f7d96a98fe..053b578601 100644 --- a/api/src/main/java/net/kyori/adventure/text/renderer/TranslatableComponentRenderer.java +++ b/api/src/main/java/net/kyori/adventure/text/renderer/TranslatableComponentRenderer.java @@ -223,6 +223,7 @@ protected Component renderTranslatable(TranslatableComponent component, final C return this.renderTranslatableInner(component, context); } + @SuppressWarnings("JdkObsolete") // The MessageFormat API requires StringBuffer. protected Component renderTranslatableInner(final TranslatableComponent component, final C context) { final MessageFormat format = this.translate(component.key(), component.fallback(), context); if (format == null) return this.optionallyRenderChildrenAndStyle(component, context); diff --git a/api/src/test/java/net/kyori/adventure/text/AbstractComponentTest.java b/api/src/test/java/net/kyori/adventure/text/AbstractComponentTest.java index d39aad5f22..92505124b2 100644 --- a/api/src/test/java/net/kyori/adventure/text/AbstractComponentTest.java +++ b/api/src/test/java/net/kyori/adventure/text/AbstractComponentTest.java @@ -46,6 +46,7 @@ import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; +@SuppressWarnings("unchecked") // We do a whole bunch of unchecked casts, but it's okay because if any fail the tests will fail too. abstract class AbstractComponentTest, B extends ComponentBuilder> { abstract B builder(); diff --git a/api/src/test/java/net/kyori/adventure/text/ComponentCompactingTest.java b/api/src/test/java/net/kyori/adventure/text/ComponentCompactingTest.java index 68b190ba5e..e2e2772dac 100644 --- a/api/src/test/java/net/kyori/adventure/text/ComponentCompactingTest.java +++ b/api/src/test/java/net/kyori/adventure/text/ComponentCompactingTest.java @@ -319,6 +319,7 @@ void testJoinTextWithChildren() { assertEquals(expectedCompact, notCompact.compact()); } + @SuppressWarnings("UnusedMethod") // It is used literaly right below this. private static boolean shouldSkipSimplifyingStyleForBlankComponents() { return !ComponentCompaction.SIMPLIFY_STYLE_FOR_BLANK_COMPONENTS; } diff --git a/api/src/test/java/net/kyori/adventure/text/ComponentIteratorTest.java b/api/src/test/java/net/kyori/adventure/text/ComponentIteratorTest.java index 92e4281a51..74db51e063 100644 --- a/api/src/test/java/net/kyori/adventure/text/ComponentIteratorTest.java +++ b/api/src/test/java/net/kyori/adventure/text/ComponentIteratorTest.java @@ -73,8 +73,8 @@ public void testOfDfs() { .build(); for (final Component inner : component.iterable(ComponentIteratorType.DEPTH_FIRST)) { - if (inner instanceof TextComponent) { - final String content = ((TextComponent) inner).content(); + if (inner instanceof TextComponent textComponent) { + final String content = textComponent.content(); if (content.equals("WIDE")) { fail("WIDE before DEEP"); @@ -97,8 +97,8 @@ public void testOfBfs() { .build(); for (final Component inner : component.iterable(ComponentIteratorType.BREADTH_FIRST)) { - if (inner instanceof TextComponent) { - final String content = ((TextComponent) inner).content(); + if (inner instanceof TextComponent textComponent) { + final String content = textComponent.content(); if (content.equals("DEEP")) { fail("DEEP before WIDE"); @@ -124,9 +124,7 @@ public void testOfHover() { boolean foundEntity = false; for (final Component inner : component.iterable(ComponentIteratorType.BREADTH_FIRST, ComponentIteratorFlag.INCLUDE_HOVER_SHOW_TEXT_COMPONENT, ComponentIteratorFlag.INCLUDE_HOVER_SHOW_ENTITY_NAME)) { - if (inner instanceof TextComponent) { - final TextComponent text = (TextComponent) inner; - + if (inner instanceof TextComponent text) { if (text.content().equals("TEXT")) foundText = true; else if (text.content().equals("ENTITY")) foundEntity = true; } @@ -144,9 +142,7 @@ public void testOfTranslatableArguments() { .build(); for (final Component inner : component.iterable(ComponentIteratorType.BREADTH_FIRST, ComponentIteratorFlag.INCLUDE_TRANSLATABLE_COMPONENT_ARGUMENTS)) { - if (inner instanceof TextComponent) { - final TextComponent text = (TextComponent) inner; - + if (inner instanceof TextComponent text) { if (text.content().equals("ARG")) return; } } diff --git a/api/src/test/java/net/kyori/adventure/util/ComponentMessageThrowableTest.java b/api/src/test/java/net/kyori/adventure/util/ComponentMessageThrowableTest.java index b509cf5134..481e68f968 100644 --- a/api/src/test/java/net/kyori/adventure/util/ComponentMessageThrowableTest.java +++ b/api/src/test/java/net/kyori/adventure/util/ComponentMessageThrowableTest.java @@ -47,7 +47,6 @@ void testGetOrConvertMessage() { assertNull(ComponentMessageThrowable.getOrConvertMessage(new IllegalStateException((String) null))); } - @SuppressWarnings("serial") static class Checked extends Exception implements ComponentMessageThrowable { private final @Nullable Component componentMessage; diff --git a/api/src/test/java/net/kyori/adventure/util/TicksTest.java b/api/src/test/java/net/kyori/adventure/util/TicksTest.java index e01e4fe9a5..bfe5c30962 100644 --- a/api/src/test/java/net/kyori/adventure/util/TicksTest.java +++ b/api/src/test/java/net/kyori/adventure/util/TicksTest.java @@ -29,6 +29,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; class TicksTest { + @SuppressWarnings("JavaDurationGetSecondsToToSeconds") // This is intentional. @Test void testTicks() { final Duration d0 = Ticks.duration(10); diff --git a/build-logic/src/main/kotlin/adventure.common-conventions.gradle.kts b/build-logic/src/main/kotlin/adventure.common-conventions.gradle.kts index 1b73ffe9b2..96c0e38cb8 100644 --- a/build-logic/src/main/kotlin/adventure.common-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/adventure.common-conventions.gradle.kts @@ -85,6 +85,7 @@ tasks { javadoc { val options = options as? StandardJavadocDocletOptions ?: return@javadoc options.tags( + "obsolete:a:Obsolete", "sinceMinecraft:a:Since Minecraft:", "obsoleteSinceMinecraft:a:Obsolete since Minecraft", ) @@ -101,6 +102,10 @@ tasks { disable("ReferenceEquality") // lots of comparison against EMPTY objects disable("CanIgnoreReturnValueSuggester") // suggests errorprone annotation, not JB Contract annotation } + + options.compilerArgs.add("-Xlint:all") + options.compilerArgs.add("-Xlint:-processing") // unclaimed ap warnings are not needed + options.compilerArgs.add("-Xlint:-serial") // nobody cares about serialization } } diff --git a/nbt/src/main/java/net/kyori/adventure/nbt/ByteBinaryTag.java b/nbt/src/main/java/net/kyori/adventure/nbt/ByteBinaryTag.java index 0b9bc9a615..0dbe3eb9c0 100644 --- a/nbt/src/main/java/net/kyori/adventure/nbt/ByteBinaryTag.java +++ b/nbt/src/main/java/net/kyori/adventure/nbt/ByteBinaryTag.java @@ -28,6 +28,7 @@ * * @since 4.0.0 */ +@SuppressWarnings("ClassInitializationDeadlock") // It's fine. public sealed interface ByteBinaryTag extends NumberBinaryTag permits ByteBinaryTagImpl { /** * A tag with the value {@code 0}. diff --git a/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/ComponentLoggingEventBuilderImpl.java b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/ComponentLoggingEventBuilderImpl.java index 09ade3be01..487b494f8c 100644 --- a/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/ComponentLoggingEventBuilderImpl.java +++ b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/ComponentLoggingEventBuilderImpl.java @@ -53,8 +53,8 @@ final class ComponentLoggingEventBuilderImpl extends DefaultLoggingEventBuilder } private @Nullable Object maybeSerialize(final @Nullable Object input) { - if (input instanceof ComponentLike) { - return this.serialize(((ComponentLike) input).asComponent()); + if (input instanceof ComponentLike componentLike) { + return this.serialize(componentLike.asComponent()); } else { return input; } diff --git a/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/NoOpComponentLoggingEventBuilderImpl.java b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/NoOpComponentLoggingEventBuilderImpl.java index 7181f2b33a..53f57fd029 100644 --- a/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/NoOpComponentLoggingEventBuilderImpl.java +++ b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/NoOpComponentLoggingEventBuilderImpl.java @@ -25,10 +25,10 @@ import java.util.function.Supplier; import net.kyori.adventure.text.ComponentLike; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.slf4j.Marker; +@SuppressWarnings("OverridingMethodInconsistentArgumentNamesChecker") // This false flags basically every method here. final class NoOpComponentLoggingEventBuilderImpl implements ComponentLoggingEventBuilder { static final NoOpComponentLoggingEventBuilderImpl INSTANCE = new NoOpComponentLoggingEventBuilderImpl(); @@ -36,52 +36,52 @@ private NoOpComponentLoggingEventBuilderImpl() { } @Override - public @NotNull ComponentLoggingEventBuilder setCause(final @Nullable Throwable cause) { + public ComponentLoggingEventBuilder setCause(final @Nullable Throwable cause) { return this; } @Override - public @NotNull ComponentLoggingEventBuilder addMarker(final @NotNull Marker marker) { + public ComponentLoggingEventBuilder addMarker(final Marker marker) { return this; } @Override - public @NotNull ComponentLoggingEventBuilder addArgument(final @Nullable Object p) { + public ComponentLoggingEventBuilder addArgument(final @Nullable Object p) { return this; } @Override - public @NotNull ComponentLoggingEventBuilder addArgument(final @Nullable Supplier objectSupplier) { + public ComponentLoggingEventBuilder addArgument(final @Nullable Supplier objectSupplier) { return this; } @Override - public @NotNull ComponentLoggingEventBuilder addKeyValue(final @Nullable String key, final @Nullable Object value) { + public ComponentLoggingEventBuilder addKeyValue(final @Nullable String key, final @Nullable Object value) { return this; } @Override - public @NotNull ComponentLoggingEventBuilder addKeyValue(final @Nullable String key, final Supplier valueSupplier) { + public ComponentLoggingEventBuilder addKeyValue(final @Nullable String key, final Supplier valueSupplier) { return this; } @Override - public @NotNull ComponentLoggingEventBuilder setMessage(final @Nullable String message) { + public ComponentLoggingEventBuilder setMessage(final @Nullable String message) { return this; } @Override - public @NotNull ComponentLoggingEventBuilder setMessage(final @Nullable ComponentLike message) { + public ComponentLoggingEventBuilder setMessage(final @Nullable ComponentLike message) { return this; } @Override - public @NotNull ComponentLoggingEventBuilder setMessage(final @NotNull Supplier messageSupplier) { + public ComponentLoggingEventBuilder setMessage(final Supplier messageSupplier) { return this; } @Override - public @NotNull ComponentLoggingEventBuilder setComponentMessage(final @NotNull Supplier messageSupplier) { + public ComponentLoggingEventBuilder setComponentMessage(final Supplier messageSupplier) { return this; } @@ -122,10 +122,10 @@ public void log(final @Nullable ComponentLike message, final @Nullable Object ar } @Override - public void log(final @Nullable ComponentLike message, final @Nullable Object @NotNull ... args) { + public void log(final @Nullable ComponentLike message, final @Nullable Object... args) { } @Override - public void logComponent(final @NotNull Supplier messageSupplier) { + public void logComponent(final Supplier messageSupplier) { } } diff --git a/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/WrappingComponentLoggerImpl.java b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/WrappingComponentLoggerImpl.java index 2dc8741760..135040278e 100644 --- a/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/WrappingComponentLoggerImpl.java +++ b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/WrappingComponentLoggerImpl.java @@ -33,6 +33,7 @@ import org.slf4j.event.Level; import org.slf4j.spi.LocationAwareLogger; +@SuppressWarnings("OverridingMethodInconsistentArgumentNamesChecker") // This false flags basically every method here. final class WrappingComponentLoggerImpl implements ComponentLogger { private static final String FQCN = WrappingComponentLoggerImpl.class.getName(); diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/TagInternals.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/TagInternals.java index a435338e4f..bf2acdd75f 100644 --- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/TagInternals.java +++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/TagInternals.java @@ -27,7 +27,6 @@ import java.util.Objects; import java.util.regex.Pattern; import net.kyori.adventure.text.minimessage.tag.TagPattern; -import org.intellij.lang.annotations.RegExp; import org.jetbrains.annotations.ApiStatus; /** @@ -37,8 +36,7 @@ */ @ApiStatus.Internal public final class TagInternals { - public static final @RegExp String TAG_NAME_REGEX = "[!?#]?[a-z0-9_-]*"; - private static final Pattern TAG_NAME_PATTERN = Pattern.compile(TAG_NAME_REGEX); + private static final Pattern TAG_NAME_PATTERN = Pattern.compile(TagPattern.TAG_NAME_REGEX); private TagInternals() { } diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/parser/TokenParser.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/parser/TokenParser.java index 3a92db419d..d983854fa1 100644 --- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/parser/TokenParser.java +++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/internal/parser/TokenParser.java @@ -334,7 +334,7 @@ private static void parseSecondPass(final String message, final List toke } switch (state) { - case NORMAL: + case NORMAL -> { // Values are split by : unless it's in a URL if (codePoint == SEPARATOR) { if (boundsCheck(message, i, 2) && message.charAt(i + 1) == '/' && message.charAt(i + 2) == '/') { @@ -352,12 +352,12 @@ private static void parseSecondPass(final String message, final List toke state = SecondPassState.STRING; currentStringChar = (char) codePoint; } - break; - case STRING: + } + case STRING -> { if (codePoint == currentStringChar) { state = SecondPassState.NORMAL; } - break; + } } } @@ -484,6 +484,7 @@ private static RootNode buildTree( node.addChild(new TextNode(node, token, message)); } } + default -> { } // no-op } } diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/StylingTagImpl.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/StylingTagImpl.java index a5cdd8d1e9..2ba3920c06 100644 --- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/StylingTagImpl.java +++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/StylingTagImpl.java @@ -27,6 +27,7 @@ import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.StyleBuilderApplicable; +@SuppressWarnings("ArrayRecordComponent") // It's okay, side effects aren't important here. record StylingTagImpl(StyleBuilderApplicable[] styles) implements Inserting { @Override diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/Tag.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/Tag.java index 5951681b95..361996dc0b 100644 --- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/Tag.java +++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/Tag.java @@ -33,6 +33,7 @@ import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.StyleBuilderApplicable; import net.kyori.adventure.text.minimessage.internal.parser.node.TagPart; +import org.jspecify.annotations.Nullable; import static java.util.Objects.requireNonNull; @@ -127,7 +128,8 @@ static Tag styling(final Consumer styles) { * @return a tag for these actions * @since 4.10.0 */ - static Tag styling(final StyleBuilderApplicable... actions) { + @SuppressWarnings("overloads") // It's fine, it's not really correct. + static Tag styling(final @Nullable StyleBuilderApplicable... actions) { requireNonNull(actions, "actions"); for (int i = 0, length = actions.length; i < length; i++) { if (actions[i] == null) { diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/TagPattern.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/TagPattern.java index ff2ab6919b..a0e02c43ce 100644 --- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/TagPattern.java +++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/TagPattern.java @@ -27,8 +27,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import net.kyori.adventure.text.minimessage.internal.TagInternals; import org.intellij.lang.annotations.Pattern; +import org.intellij.lang.annotations.RegExp; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.LOCAL_VARIABLE; @@ -36,12 +36,20 @@ import static java.lang.annotation.ElementType.PARAMETER; /** - * A {@link Tag} name must match this pattern. This is used to validate tag names. Uses [!?#]?[a-z0-9_-]* + * A {@link Tag} name must match this pattern. + * This is used to validate tag names. + * Uses {@link TagPattern#TAG_NAME_REGEX}. * * @since 4.14.0 */ @Documented @Retention(RetentionPolicy.CLASS) @Target({ METHOD, FIELD, PARAMETER, LOCAL_VARIABLE }) -public @Pattern(TagInternals.TAG_NAME_REGEX) @interface TagPattern { +public @Pattern(TagPattern.TAG_NAME_REGEX) @interface TagPattern { + /** + * The tag name regex. + * + * @since 5.0.0 + */ + @RegExp String TAG_NAME_REGEX = "[!?#]?[a-z0-9_-]*"; } diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/SequentialHeadTag.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/SequentialHeadTag.java index b2aaeef019..eb34b1cb01 100644 --- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/SequentialHeadTag.java +++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/SequentialHeadTag.java @@ -190,13 +190,14 @@ private enum PresentType { ID(obj -> Objects.requireNonNull(obj.id()).toString()), TEXTURE(obj -> Objects.requireNonNull(obj.texture()).asMinimalString()); + @SuppressWarnings("ImmutableEnumChecker") // It is immutable. private final Function mappingFunction; PresentType(final Function mappingFunction) { this.mappingFunction = mappingFunction; } - public String map(final PlayerHeadObjectContents obj) { + private String map(final PlayerHeadObjectContents obj) { return this.mappingFunction.apply(obj); } } diff --git a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/TransitionTag.java b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/TransitionTag.java index 9df31dd064..f00d43766a 100644 --- a/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/TransitionTag.java +++ b/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/standard/TransitionTag.java @@ -44,6 +44,7 @@ * @param negativePhase whether the phase is negative * @since 4.10.0 */ +@SuppressWarnings("ArrayRecordComponent") // It's okay, it's internal. @ApiStatus.Internal record TransitionTag( TextColor[] colors, diff --git a/text-serializer-commons/src/main/java/net/kyori/adventure/text/serializer/commons/ComponentTreeConstants.java b/text-serializer-commons/src/main/java/net/kyori/adventure/text/serializer/commons/ComponentTreeConstants.java index 86801f7dcf..02410bed4a 100644 --- a/text-serializer-commons/src/main/java/net/kyori/adventure/text/serializer/commons/ComponentTreeConstants.java +++ b/text-serializer-commons/src/main/java/net/kyori/adventure/text/serializer/commons/ComponentTreeConstants.java @@ -23,6 +23,8 @@ */ package net.kyori.adventure.text.serializer.commons; +import org.jetbrains.annotations.ApiStatus; + /** * Constants to aid in the creation and testing of tree-based component serializers. * @@ -36,7 +38,7 @@ public final class ComponentTreeConstants { public static final String SCORE = "score"; public static final String SCORE_NAME = "name"; public static final String SCORE_OBJECTIVE = "objective"; - @Deprecated + @ApiStatus.Obsolete public static final String SCORE_VALUE = "value"; public static final String SELECTOR = "selector"; public static final String KEYBIND = "keybind"; @@ -62,7 +64,7 @@ public final class ComponentTreeConstants { public static final String COLOR = "color"; public static final String SHADOW_COLOR = "shadow_color"; public static final String INSERTION = "insertion"; - @Deprecated + @ApiStatus.Obsolete public static final String CLICK_EVENT_CAMEL = "clickEvent"; public static final String CLICK_EVENT_SNAKE = "click_event"; public static final String CLICK_EVENT_ACTION = "action"; @@ -73,22 +75,22 @@ public final class ComponentTreeConstants { public static final String CLICK_EVENT_PAGE = "page"; public static final String CLICK_EVENT_ID = "id"; public static final String CLICK_EVENT_PAYLOAD = "payload"; - @Deprecated + @ApiStatus.Obsolete public static final String HOVER_EVENT_CAMEL = "hoverEvent"; public static final String HOVER_EVENT_SNAKE = "hover_event"; public static final String HOVER_EVENT_ACTION = "action"; - @Deprecated + @ApiStatus.Obsolete public static final String HOVER_EVENT_CONTENTS = "contents"; - @Deprecated + @ApiStatus.Obsolete public static final String HOVER_EVENT_VALUE = "value"; - @Deprecated + @ApiStatus.Obsolete public static final String SHOW_ENTITY_TYPE = "type"; public static final String SHOW_ENTITY_ID = "id"; public static final String SHOW_ENTITY_UUID = "uuid"; public static final String SHOW_ENTITY_NAME = "name"; public static final String SHOW_ITEM_ID = "id"; public static final String SHOW_ITEM_COUNT = "count"; - @Deprecated + @ApiStatus.Obsolete public static final String SHOW_ITEM_TAG = "tag"; public static final String SHOW_ITEM_COMPONENTS = "components"; diff --git a/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/ComponentSerializerImpl.java b/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/ComponentSerializerImpl.java index a653c27bb1..441c429097 100644 --- a/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/ComponentSerializerImpl.java +++ b/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/ComponentSerializerImpl.java @@ -294,12 +294,12 @@ private static , B extends NBTComponentBuilder> @Override public void write(final JsonWriter out, final Component value) throws IOException { if ( - value instanceof TextComponent + value instanceof TextComponent tc && value.children().isEmpty() && !value.hasStyling() && this.emitCompactTextComponent ) { - out.value(((TextComponent) value).content()); + out.value(tc.content()); return; } diff --git a/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/GsonDataComponentValueImpl.java b/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/GsonDataComponentValueImpl.java index b9c2fc6043..c5593c99b6 100644 --- a/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/GsonDataComponentValueImpl.java +++ b/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/GsonDataComponentValueImpl.java @@ -51,8 +51,7 @@ public String toString() { @Override public boolean equals(final @Nullable Object other) { if (this == other) return true; - if (other == null || getClass() != other.getClass()) return false; - final GsonDataComponentValueImpl that = (GsonDataComponentValueImpl) other; + if (!(other instanceof GsonDataComponentValueImpl that)) return false; return Objects.equals(this.element, that.element); } diff --git a/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/StyleSerializer.java b/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/StyleSerializer.java index 3852328db4..f3fd6ef01d 100644 --- a/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/StyleSerializer.java +++ b/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/StyleSerializer.java @@ -176,7 +176,7 @@ public Style read(final JsonReader in) throws IOException { style.insertion(in.nextString()); } else if (fieldName.equals(CLICK_EVENT_SNAKE) || fieldName.equals(CLICK_EVENT_CAMEL)) { in.beginObject(); - ClickEvent.Action action = null; + ClickEvent.Action action = null; String value = null; Key key = null; Integer page = null; diff --git a/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/TextColorSerializer.java b/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/TextColorSerializer.java index 9f03dfc60b..6fb8618be1 100644 --- a/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/TextColorSerializer.java +++ b/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/TextColorSerializer.java @@ -44,8 +44,8 @@ private TextColorSerializer(final boolean downsampleColor) { @Override public void write(final JsonWriter out, final TextColor value) throws IOException { - if (value instanceof NamedTextColor) { - out.value(NamedTextColor.NAMES.key((NamedTextColor) value)); + if (value instanceof NamedTextColor ntc) { + out.value(NamedTextColor.NAMES.key(ntc)); } else if (this.downsampleColor) { out.value(NamedTextColor.NAMES.key(NamedTextColor.nearestTo(value))); } else { diff --git a/text-serializer-legacy/src/main/java/net/kyori/adventure/text/serializer/legacy/LegacyComponentSerializerImpl.java b/text-serializer-legacy/src/main/java/net/kyori/adventure/text/serializer/legacy/LegacyComponentSerializerImpl.java index 900f5065c0..239d4aede9 100644 --- a/text-serializer-legacy/src/main/java/net/kyori/adventure/text/serializer/legacy/LegacyComponentSerializerImpl.java +++ b/text-serializer-legacy/src/main/java/net/kyori/adventure/text/serializer/legacy/LegacyComponentSerializerImpl.java @@ -202,7 +202,7 @@ private static boolean isHexTextColor(final TextFormat format) { private TextComponent extractUrl(final TextComponent component) { if (this.urlReplacementConfig == null) return component; final Component newComponent = component.replaceText(this.urlReplacementConfig); - if (newComponent instanceof TextComponent) return (TextComponent) newComponent; + if (newComponent instanceof TextComponent tc) return tc; return Component.text().append(newComponent).build(); } @@ -374,7 +374,7 @@ void set(final StyleState that) { this.decorations.addAll(that.decorations); } - public void clear() { + private void clear() { this.color = null; this.decorations.clear(); } @@ -393,6 +393,7 @@ void apply(final Style component) { this.needsReset = true; } } + case NOT_SET -> { } // do nothing } } } From 559d33773a7b2afedb0326f5dc38d4268901fe95 Mon Sep 17 00:00:00 2001 From: Kieran Wallbanks Date: Thu, 26 Mar 2026 15:35:39 +0000 Subject: [PATCH 06/10] fix(gson): Better handle `null` input This still isn't perfect, but we shouldn't break the contract and return `null` when we parse any other primitive string as a text component. --- .../text/serializer/commons/ComponentTreeConstants.java | 1 + .../text/serializer/gson/GsonComponentSerializerImpl.java | 2 ++ .../text/serializer/json/JSONComponentSerializerTest.java | 6 ++++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/text-serializer-commons/src/main/java/net/kyori/adventure/text/serializer/commons/ComponentTreeConstants.java b/text-serializer-commons/src/main/java/net/kyori/adventure/text/serializer/commons/ComponentTreeConstants.java index 02410bed4a..e4498d8466 100644 --- a/text-serializer-commons/src/main/java/net/kyori/adventure/text/serializer/commons/ComponentTreeConstants.java +++ b/text-serializer-commons/src/main/java/net/kyori/adventure/text/serializer/commons/ComponentTreeConstants.java @@ -93,6 +93,7 @@ public final class ComponentTreeConstants { @ApiStatus.Obsolete public static final String SHOW_ITEM_TAG = "tag"; public static final String SHOW_ITEM_COMPONENTS = "components"; + public static final String NULL = "null"; private ComponentTreeConstants() { throw new IllegalStateException("Cannot instantiate"); diff --git a/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/GsonComponentSerializerImpl.java b/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/GsonComponentSerializerImpl.java index 37e97e761f..9c8689ee12 100644 --- a/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/GsonComponentSerializerImpl.java +++ b/text-serializer-gson/src/main/java/net/kyori/adventure/text/serializer/gson/GsonComponentSerializerImpl.java @@ -36,6 +36,7 @@ import org.jspecify.annotations.Nullable; import static java.util.Objects.requireNonNull; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.NULL; final class GsonComponentSerializerImpl implements GsonComponentSerializer { private static final Optional SERVICE = Services.service(Provider.class); @@ -85,6 +86,7 @@ public UnaryOperator populator() { @Override public Component deserialize(final String string) { + if (NULL.equals(string)) return Component.text(NULL); return this.serializer().fromJson(string, Component.class); } diff --git a/text-serializer-json/src/testFixtures/java/net/kyori/adventure/text/serializer/json/JSONComponentSerializerTest.java b/text-serializer-json/src/testFixtures/java/net/kyori/adventure/text/serializer/json/JSONComponentSerializerTest.java index 1f9e384fe0..d2511c8fa9 100644 --- a/text-serializer-json/src/testFixtures/java/net/kyori/adventure/text/serializer/json/JSONComponentSerializerTest.java +++ b/text-serializer-json/src/testFixtures/java/net/kyori/adventure/text/serializer/json/JSONComponentSerializerTest.java @@ -29,14 +29,16 @@ import net.kyori.adventure.text.serializer.commons.ComponentTreeConstants; import org.junit.jupiter.api.Test; +import static net.kyori.adventure.text.serializer.commons.ComponentTreeConstants.NULL; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; final class JSONComponentSerializerTest extends SerializerTest { @Test void testDeserializeNull() { - assertNull(JSONComponentSerializer.json().deserialize("null")); + assertNotNull(JSONComponentSerializer.json().deserialize(NULL)); + assertEquals(Component.text(NULL), JSONComponentSerializer.json().deserialize(NULL)); } @Test From c3ce67db847776a6e05311179f33541af09f2a63 Mon Sep 17 00:00:00 2001 From: Jackson Campbell Date: Thu, 28 May 2026 12:54:10 -0400 Subject: [PATCH 07/10] Resolving missed merge conflict --- .../main/kotlin/adventure.common-conventions.gradle.kts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/build-logic/src/main/kotlin/adventure.common-conventions.gradle.kts b/build-logic/src/main/kotlin/adventure.common-conventions.gradle.kts index 8a8d6f5227..0e36d1f76b 100644 --- a/build-logic/src/main/kotlin/adventure.common-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/adventure.common-conventions.gradle.kts @@ -84,15 +84,7 @@ indraCrossdoc { tasks { javadoc { val options = options as? StandardJavadocDocletOptions ?: return@javadoc -<<<<<<< turbo/no_bbv - options.tags( - "obsolete:a:Obsolete", - "sinceMinecraft:a:Since Minecraft:", - "obsoleteSinceMinecraft:a:Obsolete since Minecraft", - ) -======= options.applyCommonJavadocOptions() ->>>>>>> main/5 } jacocoTestReport { From 84e6b8c3d5860e60b292b689d65fda33188ef448 Mon Sep 17 00:00:00 2001 From: TurboJax Date: Thu, 28 May 2026 13:00:54 -0400 Subject: [PATCH 08/10] Marking Audience#activeBossBars as Unmodifiable --- api/src/main/java/net/kyori/adventure/audience/Audience.java | 4 ++-- .../java/net/kyori/adventure/audience/ForwardingAudience.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/net/kyori/adventure/audience/Audience.java b/api/src/main/java/net/kyori/adventure/audience/Audience.java index aeb23ff1b7..409219e070 100644 --- a/api/src/main/java/net/kyori/adventure/audience/Audience.java +++ b/api/src/main/java/net/kyori/adventure/audience/Audience.java @@ -49,7 +49,7 @@ import net.kyori.adventure.text.ComponentLike; import net.kyori.adventure.title.Title; import net.kyori.adventure.title.TitlePart; -import org.jetbrains.annotations.UnmodifiableView; +import org.jetbrains.annotations.Unmodifiable; /** * A receiver of Minecraft media. @@ -446,7 +446,7 @@ default void hideBossBar(final BossBar bar) { * @return an unmodifiable view of all known currently active bossbars * @since 4.14.0 */ - @UnmodifiableView + @Unmodifiable default Iterable activeBossBars() { return List.of(); } diff --git a/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java b/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java index bafd5da0e6..120f8da884 100644 --- a/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java +++ b/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java @@ -48,6 +48,7 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.UnknownNullability; +import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.UnmodifiableView; import org.jspecify.annotations.Nullable; @@ -349,7 +350,7 @@ default void hideBossBar(final BossBar bar) { } @Override - default @UnmodifiableView Iterable activeBossBars() { + default @Unmodifiable Iterable activeBossBars() { return this.audience().activeBossBars(); } From 23394c900af71ec9ce97c9060e7839dcd5f0ff64 Mon Sep 17 00:00:00 2001 From: TurboJax Date: Thu, 28 May 2026 13:04:17 -0400 Subject: [PATCH 09/10] Marking ForwardingAudience#activeBossBars as Unmodifiable --- .../java/net/kyori/adventure/audience/ForwardingAudience.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java b/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java index 120f8da884..338b194c16 100644 --- a/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java +++ b/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java @@ -167,7 +167,7 @@ default void hideBossBar(final BossBar bar) { } @Override - default @UnmodifiableView Iterable activeBossBars() { + default @Unmodifiable Iterable activeBossBars() { final Set bossBars = new HashSet<>(); for (final Audience audience : this.audiences()) { for (final BossBar bb : audience.activeBossBars()) bossBars.add(bb); From 4b8a4e7b49e593e718644a0f63dad0dd09a77ee1 Mon Sep 17 00:00:00 2001 From: Jackson Campbell Date: Thu, 28 May 2026 13:05:43 -0400 Subject: [PATCH 10/10] Expanding inline for-loop Co-authored-by: Strokkur24 --- .../java/net/kyori/adventure/audience/ForwardingAudience.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java b/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java index 338b194c16..5df0778400 100644 --- a/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java +++ b/api/src/main/java/net/kyori/adventure/audience/ForwardingAudience.java @@ -170,7 +170,9 @@ default void hideBossBar(final BossBar bar) { default @Unmodifiable Iterable activeBossBars() { final Set bossBars = new HashSet<>(); for (final Audience audience : this.audiences()) { - for (final BossBar bb : audience.activeBossBars()) bossBars.add(bb); + for (final BossBar bb : audience.activeBossBars()) { + bossBars.add(bb); + } } return bossBars;