Skip to content

Commit b51d9fd

Browse files
committed
Javadocs + Contract + XReflection String Signatures
* Improved some javadocs. * Added `@Contract` annotations to most APIs. * **[XReflection]** Using the suffix support for JetBrains `@Language` annotation, we no longer need to add semicolons or `{}` at the end of string APIs. Other than the readability improvement, this results in a slight performance improvement as well, since fewer characters are needed for parsing.
1 parent f6210b7 commit b51d9fd

29 files changed

+381
-169
lines changed

TODO.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,17 @@ developers can see and perhaps give suggestions about. Anyone is welcome to comp
1818
with a solution that doesn't involve modifying the startup arguments like Java Agents for replacing classes that
1919
access ASM generated class fields/constructors.
2020

21+
* **[ReflectiveHandleProxyProcessor]** Finish this class for people who wish to use the XReflection's direct API instead
22+
of using the annotations. This is useful for situations where annotations will seem bulky or the data is more complex
23+
and must be calculated during runtime.
24+
25+
* **[XTag]** Inline all fields. Using a `static {}` block is unnecessary and makes things really hard to track.
26+
Currently, this is not possible using IntelliJ's `Refactor -> Inline Field` feature, because you'll get a
27+
`No initializer present for the field` error. Not sure if this is a bug or some sort of tricky feature.
28+
Also, the formatting of the builder entries should in a way that the first entry is not in the same line as
29+
the builder's method. (No `FIELD = TagBuilder.simple(XMaterial.VALUE,\n`, but `FIELD = TagBuilder.simple(\n`)
30+
and each line should contain at least 3 entries, not one entry for each line.
31+
2132
* **[General]** Perhaps define a class named **XSeries** that contain general methods and information about the library
2233
including the current version and methods to enable/disable certain features that are currently handled by system
2334
properties? One thing we could do is to add an option to enable debug mode, certain exceptions that are normally
@@ -32,6 +43,8 @@ developers can see and perhaps give suggestions about. Anyone is welcome to comp
3243
* **[General]** Adding a nice logo/banner to the main GitHub page would be nice, it feels quite empty right now. I will
3344
have to spend a lot of time to design one.
3445

35-
* **[ReflectiveHandleProxyProcessor]** Finish this class for people who wish to use the XReflection's direct API instead
36-
of using the annotations. This is useful for situations where annotations will seem bulky or the data is more complex
37-
and must be calculated during runtime.
46+
* **[Documentation]** While the javadocs are pretty comprehensive for most classes, they're mostly flooded with small
47+
and
48+
technical details that most developers don't have to be concerned about. We should make a guide on the wiki with
49+
screenshots
50+
and a general overview of all the features which makes it much easier for developers to get started.

src/main/java/com/cryptomorin/xseries/base/XBase.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
package com.cryptomorin.xseries.base;
2323

2424
import org.jetbrains.annotations.ApiStatus;
25+
import org.jetbrains.annotations.Contract;
2526
import org.jetbrains.annotations.NotNull;
2627
import org.jetbrains.annotations.Nullable;
2728

@@ -68,23 +69,28 @@ public interface XBase<XForm extends XBase<XForm, BukkitForm>, BukkitForm> {
6869
* Should be used for saving data.
6970
*/
7071
@NotNull
72+
@Contract(pure = true)
7173
String name();
7274

7375
@ApiStatus.Internal
76+
@Contract(pure = true)
7477
String[] getNames();
7578

7679
/**
7780
* In most cases you should be using {@link #name()} instead.
7881
*
7982
* @return a friendly readable string name.
8083
*/
84+
@NotNull
85+
@Contract(pure = true)
8186
default String friendlyName() {
8287
return Arrays.stream(name().split("_"))
8388
.map(t -> t.charAt(0) + t.substring(1).toLowerCase(Locale.ENGLISH))
8489
.collect(Collectors.joining(" "));
8590
}
8691

8792
@Nullable
93+
@Contract(pure = true)
8894
BukkitForm get();
8995

9096
/**
@@ -99,6 +105,7 @@ default String friendlyName() {
99105
* @return true if the current version has this sound, otherwise false.
100106
* @since 1.0.0
101107
*/
108+
@Contract(pure = true)
102109
default boolean isSupported() {
103110
return get() != null;
104111
}
@@ -115,6 +122,7 @@ default boolean isSupported() {
115122
*/
116123
@SuppressWarnings("unchecked")
117124
@NotNull
125+
@Contract(pure = true)
118126
default XForm or(XForm other) {
119127
return this.isSupported() ? (XForm) this : other;
120128
}

src/main/java/com/cryptomorin/xseries/messages/ActionBar.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@ public final class ActionBar {
7373
* We're not going to support Bukkit.
7474
*/
7575
private static final boolean USE_SPIGOT_API = XReflection.of(Player.class)
76-
.inner("public static class Spigot {}")
76+
.inner("public static class Spigot")
7777
.method("public void sendMessage(" +
7878
"net.md_5.bungee.api.ChatMessageType position," +
79-
"net.md_5.bungee.api.chat.BaseComponent component);")
79+
"net.md_5.bungee.api.chat.BaseComponent component)")
8080
.exists();
8181

8282
/**

src/main/java/com/cryptomorin/xseries/profiles/ProfilesCore.java

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -81,104 +81,104 @@ public final class ProfilesCore {
8181
.imports(GameProfile.class, MinecraftSessionService.class, LoadingCache.class);
8282

8383
MinecraftClassHandle GameProfileCache = ns.ofMinecraft(
84-
"package nms.server.players; public class GameProfileCache {}"
84+
"package nms.server.players; public class GameProfileCache"
8585
).map(MinecraftMapping.SPIGOT, "UserCache");
8686

8787
try {
8888
MinecraftClassHandle CraftMetaSkull = ns.ofMinecraft(
89-
"package cb.inventory; class CraftMetaSkull extends CraftMetaItem implements SkullMeta {}"
89+
"package cb.inventory; class CraftMetaSkull extends CraftMetaItem implements SkullMeta"
9090
);
9191

9292
// This class has existed since ~v1.20.5, however Bukkit has started using it in their
9393
// classes since Paper v1.20.1b78, its function is basically similar to our Profileable class.
9494
MinecraftClassHandle ResolvableProfile =
95-
ns.ofMinecraft("package nms.world.item.component; public class ResolvableProfile {}");
95+
ns.ofMinecraft("package nms.world.item.component; public class ResolvableProfile");
9696

9797
if (ResolvableProfile.exists()) {
98-
newResolvableProfile = ResolvableProfile.constructor("public ResolvableProfile(GameProfile gameProfile);").reflect();
99-
$ResolvableProfile_gameProfile = ResolvableProfile.method("public GameProfile gameProfile();")
98+
newResolvableProfile = ResolvableProfile.constructor("public ResolvableProfile(GameProfile gameProfile)").reflect();
99+
$ResolvableProfile_gameProfile = ResolvableProfile.method("public GameProfile gameProfile()")
100100
.map(MinecraftMapping.OBFUSCATED, "f")
101101
.reflect();
102102

103-
bukkitUsesResolvableProfile = CraftMetaSkull.field("private ResolvableProfile profile;").exists();
103+
bukkitUsesResolvableProfile = CraftMetaSkull.field("private ResolvableProfile profile").exists();
104104
}
105105

106106
// @formatter:off
107107
profileGetterMeta = XReflection.any(
108-
CraftMetaSkull.field("private ResolvableProfile profile;"),
109-
CraftMetaSkull.field("private GameProfile profile;")
108+
CraftMetaSkull.field("private ResolvableProfile profile"),
109+
CraftMetaSkull.field("private GameProfile profile")
110110
).modify(FieldMemberHandle::getter).reflect();
111111
// @formatter:on
112112

113113
// @formatter:off
114114
// https://github.com/CryptoMorin/XSeries/issues/169
115115
// noinspection MethodMayBeStatic
116116
profileSetterMeta = XReflection.any(
117-
CraftMetaSkull.method("private void setProfile(ResolvableProfile profile);"),
118-
CraftMetaSkull.method("private void setProfile(GameProfile profile);"),
119-
CraftMetaSkull.field ("private GameProfile profile ;").setter()
117+
CraftMetaSkull.method("private void setProfile(ResolvableProfile profile)"),
118+
CraftMetaSkull.method("private void setProfile(GameProfile profile)"),
119+
CraftMetaSkull.field ("private GameProfile profile ").setter()
120120
).reflect();
121121
// @formatter:on
122122

123123
MinecraftClassHandle MinecraftServer = ns.ofMinecraft(
124-
"package nms.server; public abstract class MinecraftServer {}"
124+
"package nms.server; public abstract class MinecraftServer"
125125
);
126126

127127
// Added by Bukkit
128-
Object minecraftServer = MinecraftServer.method("public static MinecraftServer getServer();").reflect().invoke();
128+
Object minecraftServer = MinecraftServer.method("public static MinecraftServer getServer()").reflect().invoke();
129129

130-
minecraftSessionService = MinecraftServer.method("public MinecraftSessionService getSessionService();")
130+
minecraftSessionService = MinecraftServer.method("public MinecraftSessionService getSessionService()")
131131
.named(/* 1.21.3 */ "aq", /* 1.19.4 */ "ay", /* 1.17.1 */ "getMinecraftSessionService", "az", "ao", "am", /* 1.20.4 */ "aD", /* 1.20.6 */ "ar", /* 1.13 */ "ap")
132132
.reflect().invoke(minecraftServer);
133133

134134
{
135135
FieldMemberHandle insecureProfilesFieldHandle = ns.ofMinecraft("package com.mojang.authlib.yggdrasil;" +
136-
"public class YggdrasilMinecraftSessionService implements MinecraftSessionService {}").field().getter();
136+
"public class YggdrasilMinecraftSessionService implements MinecraftSessionService").field().getter();
137137
if (NULLABILITY_RECORD_UPDATE) {
138-
insecureProfilesFieldHandle.signature("private final LoadingCache<UUID, Optional<ProfileResult>> insecureProfiles;");
138+
insecureProfilesFieldHandle.signature("private final LoadingCache<UUID, Optional<ProfileResult>> insecureProfiles");
139139
} else {
140-
insecureProfilesFieldHandle.signature("private final LoadingCache<GameProfile, GameProfile> insecureProfiles;");
140+
insecureProfilesFieldHandle.signature("private final LoadingCache<GameProfile, GameProfile> insecureProfiles");
141141
}
142142
MethodHandle insecureProfilesField = insecureProfilesFieldHandle.reflectOrNull();
143143
if (insecureProfilesField != null) {
144144
insecureProfiles = insecureProfilesField.invoke(minecraftSessionService);
145145
}
146146
}
147147

148-
userCache = MinecraftServer.method("public GameProfileCache getProfileCache();")
148+
userCache = MinecraftServer.method("public GameProfileCache getProfileCache()")
149149
.named("at", /* 1.21.3 */ "ar", /* 1.18.2 */ "ao", /* 1.20.4 */ "ap", /* 1.20.6 */ "au")
150150
.map(MinecraftMapping.OBFUSCATED, /* 1.9.4 */ "getUserCache")
151151
.reflect().invoke(minecraftServer);
152152

153153
if (!NULLABILITY_RECORD_UPDATE) {
154154
fillProfileProperties = ns.of(MinecraftSessionService.class).method(
155-
"public GameProfile fillProfileProperties(GameProfile profile, boolean flag);"
155+
"public GameProfile fillProfileProperties(GameProfile profile, boolean flag)"
156156
).reflect();
157157
}
158158

159159
// noinspection MethodMayBeStatic
160-
UserCache_getNextOperation = GameProfileCache.method("private long getNextOperation();")
160+
UserCache_getNextOperation = GameProfileCache.method("private long getNextOperation()")
161161
.map(MinecraftMapping.OBFUSCATED, v(21, "e").v(16, "d").orElse("d")).reflectOrNull();
162162

163163
MethodMemberHandle profileByName = GameProfileCache.method().named(/* v1.17.1 */ "getProfile", "a");
164164
MethodMemberHandle profileByUUID = GameProfileCache.method().named(/* v1.17.1 */ "getProfile", "a");
165165
// @formatter:off
166166
getProfileByName = XReflection.anyOf(
167-
() -> profileByName.signature("public GameProfile get(String username);"),
168-
() -> profileByName.signature("public Optional<GameProfile> get(String username);")
167+
() -> profileByName.signature("public GameProfile get(String username)"),
168+
() -> profileByName.signature("public Optional<GameProfile> get(String username)")
169169
).reflect();
170170
getProfileByUUID = XReflection.anyOf(
171-
() -> profileByUUID.signature("public GameProfile get(UUID id);"),
172-
() -> profileByUUID.signature("public Optional<GameProfile> get(UUID id);")
171+
() -> profileByUUID.signature("public GameProfile get(UUID id)"),
172+
() -> profileByUUID.signature("public Optional<GameProfile> get(UUID id)")
173173
).reflect();
174174
// @formatter:on
175175

176-
cacheProfile = GameProfileCache.method("public void add(GameProfile profile);")
176+
cacheProfile = GameProfileCache.method("public void add(GameProfile profile)")
177177
.map(MinecraftMapping.OBFUSCATED, "a").reflect();
178178

179179
try {
180180
// Some versions don't have the public getProxy() method. It's very very inconsistent...
181-
proxy = (Proxy) MinecraftServer.field("protected final java.net.Proxy proxy;").getter()
181+
proxy = (Proxy) MinecraftServer.field("protected final java.net.Proxy proxy").getter()
182182
.map(MinecraftMapping.OBFUSCATED, v(20, 5, "h").v(20, 3, "i")
183183
.v(19, "j")
184184
.v(18, 2, "n").v(18, "o")
@@ -195,16 +195,16 @@ public final class ProfilesCore {
195195
}
196196

197197
MinecraftClassHandle CraftSkull = ns.ofMinecraft(
198-
"package cb.block; public class CraftSkull extends CraftBlockEntityState implements Skull {}"
198+
"package cb.block; public class CraftSkull extends CraftBlockEntityState implements Skull"
199199
);
200200

201201
FieldMemberHandle CraftSkull_profile = XReflection.any(
202-
CraftSkull.field("private ResolvableProfile profile;"),
203-
CraftSkull.field("private GameProfile profile;")
202+
CraftSkull.field("private ResolvableProfile profile"),
203+
CraftSkull.field("private GameProfile profile")
204204
).getHandle();
205205

206206
Property_getValue = NULLABILITY_RECORD_UPDATE ? null :
207-
ns.of(Property.class).method("public String getValue();").unreflect();
207+
ns.of(Property.class).method("public String getValue()").unreflect();
208208

209209
PROXY = proxy;
210210
USER_CACHE = userCache;
@@ -228,27 +228,27 @@ public final class ProfilesCore {
228228
ResolvableProfile$bukkitSupports = bukkitUsesResolvableProfile;
229229

230230
MinecraftClassHandle UserCacheEntry = GameProfileCache
231-
.inner("private static class GameProfileInfo {}")
231+
.inner("private static class GameProfileInfo")
232232
.map(MinecraftMapping.SPIGOT, "UserCacheEntry");
233233

234-
UserCacheEntry_getProfile = UserCacheEntry.method("public GameProfile getProfile();")
234+
UserCacheEntry_getProfile = UserCacheEntry.method("public GameProfile getProfile()")
235235
.map(MinecraftMapping.OBFUSCATED, "a").makeAccessible()
236236
.unreflect();
237-
UserCacheEntry_setLastAccess = UserCacheEntry.method("public void setLastAccess(long i);")
237+
UserCacheEntry_setLastAccess = UserCacheEntry.method("public void setLastAccess(long i)")
238238
.map(MinecraftMapping.OBFUSCATED, "a").reflectOrNull();
239239

240240
try {
241241
// private final Map<String, UserCache.UserCacheEntry> profilesByName = Maps.newConcurrentMap();
242-
UserCache_profilesByName = (Map<String, Object>) GameProfileCache.field("private final Map<String, UserCache.UserCacheEntry> profilesByName;")
242+
UserCache_profilesByName = (Map<String, Object>) GameProfileCache.field("private final Map<String, UserCache.UserCacheEntry> profilesByName")
243243
.getter().map(MinecraftMapping.OBFUSCATED, v(17, "e").v(16, 2, "c").v(9, "d").orElse("c"))
244244
.reflect().invoke(userCache);
245245
// private final Map<UUID, UserCache.UserCacheEntry> profilesByUUID = Maps.newConcurrentMap();
246-
UserCache_profilesByUUID = (Map<UUID, Object>) GameProfileCache.field("private final Map<UUID, UserCache.UserCacheEntry> profilesByUUID;")
246+
UserCache_profilesByUUID = (Map<UUID, Object>) GameProfileCache.field("private final Map<UUID, UserCache.UserCacheEntry> profilesByUUID")
247247
.getter().map(MinecraftMapping.OBFUSCATED, v(17, "f").v(16, 2, "d").v(9, "e").orElse("d"))
248248
.reflect().invoke(userCache);
249249

250250
// private final Deque<GameProfile> f = new LinkedBlockingDeque(); Removed in v1.16
251-
// MethodHandle deque = GameProfileCache.field("private final Deque<GameProfile> f;")
251+
// MethodHandle deque = GameProfileCache.field("private final Deque<GameProfile> f")
252252
// .getter().reflectOrNull();
253253
} catch (Throwable e) {
254254
throw new IllegalStateException("Failed to initialize ProfilesCore", e);

0 commit comments

Comments
 (0)