diff --git a/src/main/java/ch/njol/skript/doc/Categorizable.java b/src/main/java/ch/njol/skript/doc/Categorizable.java new file mode 100644 index 00000000000..ea42e427f44 --- /dev/null +++ b/src/main/java/ch/njol/skript/doc/Categorizable.java @@ -0,0 +1,21 @@ +package ch.njol.skript.doc; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Unmodifiable; + +import java.util.Set; + +/** + * Represents anything that can be categorized. + */ +@FunctionalInterface +public interface Categorizable { + + /** + * Returns the documentation categories which this object belongs to. + * + * @return The categories of this object. + */ + @Unmodifiable @NotNull Set categories(); + +} diff --git a/src/main/java/ch/njol/skript/doc/Category.java b/src/main/java/ch/njol/skript/doc/Category.java new file mode 100644 index 00000000000..f50b393d3c6 --- /dev/null +++ b/src/main/java/ch/njol/skript/doc/Category.java @@ -0,0 +1,90 @@ +package ch.njol.skript.doc; + +import com.google.common.base.Preconditions; +import org.jetbrains.annotations.NotNull; +import org.skriptlang.skript.addon.AddonModule; + +import java.util.Set; + +/** + * Represents a category a documented element can belong to. + */ +public interface Category { + + Category ENTITIES = new CategoryImpl("Entities", "entity", "entities", "animal", "panda", "allay", + "zombie", "goat", "horse", "pig", "fish", "villager", "bee"); + Category BREEDING = new CategoryImpl("Breeding"); + Category PLAYERS = new CategoryImpl("Players", "player", "operator"); + Category DAMAGE_SOURCES = new CategoryImpl("Damage Sources", "damage source"); + Category BLOCKS = new CategoryImpl("Blocks", "block"); + Category STRINGS = new CategoryImpl("Strings", "string", "text"); + Category COMMANDS = new CategoryImpl("Commands", "command"); + Category ITEMS = new CategoryImpl("Items", "item", "enchantment", "lore", "tooltip", "banner"); + Category WORLDS = new CategoryImpl("Worlds", "world"); + Category SCRIPTS = new CategoryImpl("Scripts", "script"); + Category DISPLAYS = new CategoryImpl("Displays", "display"); + Category TIME = new CategoryImpl("Time", "time", "unix"); + Category UUIDS = new CategoryImpl("UUIDs", "uuid"); + Category DATES = new CategoryImpl("Dates", "date"); + Category LOCATIONS = new CategoryImpl("Locations", "location"); + Category MATH = new CategoryImpl("Math", "angle", "degree", "radian", + "arithmetic", "nan", "round", "rounds", "root", "quaternion", "permutations", + "combinations", "numbers", "infinity", "exponential"); + Category VECTORS = new CategoryImpl("Vectors", Category.MATH, "vector"); + + /** + * @return The display name of this category. + */ + @NotNull String name(); + + /** + * @return The parent category of this category. + */ + Category parent(); + + /** + * Adds a module to this category. + * + * @param module The module to add. + */ + void addModule(@NotNull Class module); + + /** + * @return The modules that are represented by this category. + */ + @NotNull Set> modules(); + + /** + * Creates a new category. + * + * @param name The name. + * @return The new category. + */ + static Category of(@NotNull String name) { + Preconditions.checkNotNull(name, "name cannot be null"); + + return new CategoryImpl(name); + } + + /** + * Creates a new category. + * + * @param name The name. + * @param category The category. + * @return The new category. + */ + static Category of(@NotNull String name, @NotNull Category category) { + Preconditions.checkNotNull(name, "name cannot be null"); + Preconditions.checkNotNull(category, "category cannot be null"); + + return new CategoryImpl(name, category); + } + + /** + * @return All registered categories. + */ + static Set values() { + return CategoryImpl.getInstances(); + } + +} diff --git a/src/main/java/ch/njol/skript/doc/CategoryImpl.java b/src/main/java/ch/njol/skript/doc/CategoryImpl.java new file mode 100644 index 00000000000..892871ce4b4 --- /dev/null +++ b/src/main/java/ch/njol/skript/doc/CategoryImpl.java @@ -0,0 +1,65 @@ +package ch.njol.skript.doc; + +import com.google.common.base.Preconditions; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Unmodifiable; +import org.skriptlang.skript.addon.AddonModule; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + +final class CategoryImpl implements Category { + + private static final Set instances = new HashSet<>(); + private final String name; + private final Category parent; + private final Set keywords; + private final Set> modules; + + static Set getInstances() { + return instances; + } + + CategoryImpl(String name, String... keywords) { + this(name, null, keywords); + } + + CategoryImpl(String name, Category parent, String... keywords) { + instances.add(this); + this.name = name; + this.parent = parent; + this.keywords = Arrays.stream(keywords) + .map(String::toLowerCase) + .collect(Collectors.toUnmodifiableSet()); + this.modules = new HashSet<>(); + } + + @Override + public @NotNull String name() { + return name; + } + + @Override + public Category parent() { + return parent; + } + + public @NotNull Set keywords() { + return keywords; + } + + @Override + public void addModule(@NotNull Class module) { + Preconditions.checkNotNull(module, "module cannot be null"); + + modules.add(module); + } + + @Override + public @Unmodifiable @NotNull Set> modules() { + return Set.copyOf(modules); + } + +} diff --git a/src/main/java/ch/njol/skript/doc/JSONGenerator.java b/src/main/java/ch/njol/skript/doc/JSONGenerator.java index c4a765b9e97..5bac51578d6 100644 --- a/src/main/java/ch/njol/skript/doc/JSONGenerator.java +++ b/src/main/java/ch/njol/skript/doc/JSONGenerator.java @@ -22,6 +22,7 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.addon.AddonModule; import org.skriptlang.skript.addon.SkriptAddon; import org.skriptlang.skript.bukkit.registration.BukkitRegistryKeys; import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos; @@ -30,6 +31,8 @@ import org.skriptlang.skript.lang.structure.Structure; import org.skriptlang.skript.registration.DefaultSyntaxInfos; import org.skriptlang.skript.registration.SyntaxInfo; +import org.skriptlang.skript.registration.SyntaxOrigin; +import org.skriptlang.skript.registration.SyntaxOrigin.ModuleOrigin; import org.skriptlang.skript.registration.SyntaxRegistry; import java.io.File; @@ -179,6 +182,9 @@ private static JsonObject generatedAnnotatedElement(SyntaxInfo syntaxInfo) { syntaxJsonObject.add("returns", getExpressionReturnTypes(expression)); } + syntaxJsonObject.add("categories", getCategoriesArray(syntaxInfo.origin(), name.value(), + description == null ? null : List.of(description.value()), syntaxInfo.patterns())); + return syntaxJsonObject; } @@ -240,7 +246,7 @@ private static JsonObject generateEventElement(BukkitSyntaxInfos.Event info) syntaxJsonObject.add("requirements", convertToJsonArray(info.requiredPlugins().toArray(new String[0]))); syntaxJsonObject.add("examples", convertToJsonArray(info.examples().toArray(new String[0]))); syntaxJsonObject.add("eventValues", getEventValues(info)); - syntaxJsonObject.add("keywords", convertToJsonArray(info.keywords().toArray(new String[0]))); + syntaxJsonObject.add("categories", getCategoriesArray(info.origin(), info.name(), info.description(), info.patterns())); return syntaxJsonObject; } @@ -386,6 +392,9 @@ private static JsonObject generateClassInfoElement(ClassInfo classInfo) { syntaxJsonObject.add("description", convertToJsonArray(classInfo.getDescription())); syntaxJsonObject.add("requirements", convertToJsonArray(classInfo.getRequiredPlugins())); syntaxJsonObject.add("examples", convertToJsonArray(classInfo.getExamples())); + syntaxJsonObject.add("categories", getCategoriesArray(null, + Objects.requireNonNullElse(classInfo.getDocName(), classInfo.getCodeName()), + List.of(classInfo.getDescription()), null)); syntaxJsonObject.add("properties", getClassInfoProperties(classInfo)); @@ -528,6 +537,7 @@ private static JsonObject generateFunctionElement(Function function) { String functionSignature = function.getSignature().toString(false, false); functionJsonObject.add("patterns", convertToJsonArray(functionSignature)); + functionJsonObject.add("categories", getCategoriesArray(null, function.getName(), List.of(function.getDescription()), null)); return functionJsonObject; } @@ -579,6 +589,91 @@ private static JsonArray cleanPatterns(String... strings) { return convertToJsonArray(strings); } + /** + * Returns the category name of an element given its origin, name, description and patterns. + * + *

Attempts to find a category by using pattern first. + * If this has no results, then it will use the name and description. + *

+ * + * @param origin The origin of this element. + * @param name The name of this element. + * @param description The description of this element. + * @param patterns The patterns of this element. + * @return The category name, or null if none is found. + */ + private static @Nullable JsonArray getCategoriesArray( + @Nullable SyntaxOrigin origin, @NotNull String name, + @Nullable Collection description, @Nullable Collection patterns + ) { + JsonArray categories = new JsonArray(); + if (origin instanceof ModuleOrigin elementOrigin) { + Class moduleClass = elementOrigin.module().getClass(); + for (Category category : Category.values()) { + if (category.modules().contains(moduleClass)) { + categories.add(getCategoryJson(category)); + } + } + return categories; + } + + if (patterns == null) patterns = List.of(); + JsonArray first = getCategories(String.join("", patterns)); + if (!first.isEmpty()) { + return first; + } + if (description == null) description = List.of(); + + JsonArray second = getCategories(name + String.join("", description) + String.join("", patterns)); + if (!second.isEmpty()) { + return second; + } + return null; + } + + /** + * Attempts to find the categories based on the input. + * + * @param input The input. + * @return The categories, or null if none are found. + */ + private static @NotNull JsonArray getCategories(@NotNull String input) { + String lower = input.toLowerCase(); + JsonArray options = new JsonArray(); + for (Category category : Category.values()) { + if (!(category instanceof CategoryImpl impl)) { + break; + } + + for (String keyword : impl.keywords()) { + if (lower.contains(keyword)) { + options.add(getCategoryJson(category)); + break; + } + } + } + + return options; + } + + /** + * Transforms a category into a json object. + * @param category The category. + * @return The transformed category. + */ + private static JsonObject getCategoryJson(@NotNull Category category) { + JsonObject object = new JsonObject(); + + object.addProperty("name", category.name()); + if (category.parent() != null) { + object.addProperty("parent", category.parent().name()); + } else { + object.add("parent", null); + } + + return object; + } + /** * Gets the json object representing the addon. * diff --git a/src/main/java/org/skriptlang/skript/addon/AddonModule.java b/src/main/java/org/skriptlang/skript/addon/AddonModule.java index 16a414ddfa6..c7723821d27 100644 --- a/src/main/java/org/skriptlang/skript/addon/AddonModule.java +++ b/src/main/java/org/skriptlang/skript/addon/AddonModule.java @@ -2,6 +2,10 @@ import org.jetbrains.annotations.ApiStatus; import org.skriptlang.skript.Skript; +import org.skriptlang.skript.registration.SyntaxInfo; +import org.skriptlang.skript.registration.SyntaxOrigin; +import org.skriptlang.skript.registration.SyntaxRegistry; +import org.skriptlang.skript.registration.SyntaxRegistry.Key; /** * A module is a component of a {@link SkriptAddon} used for registering syntax and other {@link Skript} components. @@ -44,4 +48,51 @@ default boolean canLoad(SkriptAddon addon) { return true; } + /** + * Registers syntax such that it belongs to the current module. + * + * @param addon The addon this module belongs to. + * @param registry The registry to add this syntax to. + * @param cls The syntax info. + * @param The type of syntax. + */ + @ApiStatus.Experimental + default > void register(SkriptAddon addon, Key registry, I cls) { + register(addon, addon.syntaxRegistry(), registry, cls); + } + + /** + * Registers syntax such that it belongs to the current module. + * + * @param addon The addon this module belongs to. + * @param registry The registry to add this syntax to. + * @param classes The syntax infos. + * @param The type of syntax. + */ + @ApiStatus.Experimental + @SuppressWarnings("unchecked") + default > void register(SkriptAddon addon, Key registry, I... classes) { + SyntaxRegistry syntaxRegistry = addon.syntaxRegistry(); + for (I cls : classes) { + register(addon, syntaxRegistry, registry, cls); + } + } + + /** + * Registers syntax such that it belongs to the current module. + * + * @param addon The addon this module belongs to. + * @param syntaxRegistry The syntax registry. + * @param registry The registry to add this syntax to. + * @param cls The syntax info. + * @param The type of syntax. + */ + @ApiStatus.Experimental + default > void register(SkriptAddon addon, SyntaxRegistry syntaxRegistry, Key registry, I cls) { + //noinspection unchecked + syntaxRegistry.register(registry, (I) cls.toBuilder() + .origin(SyntaxOrigin.of(addon, this)) + .build()); + } + } diff --git a/src/main/java/org/skriptlang/skript/addon/SkriptAddon.java b/src/main/java/org/skriptlang/skript/addon/SkriptAddon.java index d99ac58085b..d2a0d4ee540 100644 --- a/src/main/java/org/skriptlang/skript/addon/SkriptAddon.java +++ b/src/main/java/org/skriptlang/skript/addon/SkriptAddon.java @@ -1,5 +1,7 @@ package org.skriptlang.skript.addon; +import ch.njol.skript.doc.Categorizable; +import ch.njol.skript.doc.Category; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; import org.skriptlang.skript.Skript; @@ -10,6 +12,7 @@ import java.util.Arrays; import java.util.List; +import java.util.Set; import java.util.function.Supplier; /** @@ -100,6 +103,13 @@ default void loadModules(AddonModule... modules) { } for (AddonModule module : filtered) { module.load(this); + + if (module instanceof Categorizable categorizable) { + Set categories = categorizable.categories(); + for (Category category : categories) { + category.addModule(module.getClass()); + } + } } } diff --git a/src/main/java/org/skriptlang/skript/bukkit/damagesource/DamageSourceModule.java b/src/main/java/org/skriptlang/skript/bukkit/damagesource/DamageSourceModule.java index 3a286a3c218..cd8b2f37580 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/damagesource/DamageSourceModule.java +++ b/src/main/java/org/skriptlang/skript/bukkit/damagesource/DamageSourceModule.java @@ -3,6 +3,8 @@ import ch.njol.skript.Skript; import ch.njol.skript.classes.ClassInfo; import ch.njol.skript.classes.registry.RegistryClassInfo; +import ch.njol.skript.doc.Categorizable; +import ch.njol.skript.doc.Category; import ch.njol.skript.expressions.base.EventValueExpression; import ch.njol.skript.registrations.Classes; import ch.njol.skript.registrations.EventValues; @@ -11,12 +13,16 @@ import org.bukkit.damage.DamageType; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDeathEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Unmodifiable; import org.skriptlang.skript.addon.AddonModule; import org.skriptlang.skript.addon.SkriptAddon; +import org.skriptlang.skript.bukkit.damagesource.elements.*; +import org.skriptlang.skript.registration.SyntaxRegistry; -import java.io.IOException; +import java.util.Set; -public class DamageSourceModule implements AddonModule { +public class DamageSourceModule implements AddonModule, Categorizable { @Override public boolean canLoad(SkriptAddon addon) { @@ -54,11 +60,19 @@ public void init(SkriptAddon addon) { @Override public void load(SkriptAddon addon) { - try { - Skript.getAddonInstance().loadClasses("org.skriptlang.skript.bukkit.damagesource", "elements"); - } catch (IOException e) { - throw new RuntimeException(e); - } + register(addon, SyntaxRegistry.CONDITION, + CondScalesWithDifficulty.info(), CondWasIndirect.info()); + + register(addon, SyntaxRegistry.EXPRESSION, + ExprCausingEntity.info(), ExprCreatedDamageSource.info(), + ExprDamageLocation.info(), ExprDamageType.info(), + ExprDirectEntity.info(), ExprFoodExhaustion.info(), + ExprSecDamageSource.info(), ExprSourceLocation.info()); + } + + @Override + public @Unmodifiable @NotNull Set categories() { + return Set.of(Category.DAMAGE_SOURCES); } } diff --git a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/CondScalesWithDifficulty.java b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/CondScalesWithDifficulty.java index 0b1f2c2a72a..23412f63a10 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/CondScalesWithDifficulty.java +++ b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/CondScalesWithDifficulty.java @@ -1,6 +1,5 @@ package org.skriptlang.skript.bukkit.damagesource.elements; -import ch.njol.skript.Skript; import ch.njol.skript.conditions.base.PropertyCondition; import ch.njol.skript.doc.*; import ch.njol.skript.lang.Expression; @@ -11,24 +10,27 @@ import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; import org.skriptlang.skript.bukkit.damagesource.DamageSourceExperimentSyntax; +import org.skriptlang.skript.registration.SyntaxInfo; @Name("Damage Source - Does Scale With Difficulty") @Description("Whether the damage from a damage source scales with the difficulty of the server.") @Example(""" - on death: - if event-damage source scales damage with difficulty: - """) + on death: + if event-damage source scales damage with difficulty: + """) @Since("2.12") @RequiredPlugins("Minecraft 1.20.4+") -@SuppressWarnings("UnstableApiUsage") public class CondScalesWithDifficulty extends PropertyCondition implements DamageSourceExperimentSyntax { - static { - Skript.registerCondition(CondScalesWithDifficulty.class, - "%damagesources% ((does|do) scale|scales) damage with difficulty", - "%damagesources% (do not|don't|does not|doesn't) scale damage with difficulty", - "%damagesources%'[s] damage ((does|do) scale|scales) with difficulty", - "%damagesources%'[s] damage (do not|don't|does not|doesn't) scale with difficulty"); + public static SyntaxInfo info() { + return SyntaxInfo.builder(CondScalesWithDifficulty.class) + .priority(DEFAULT_PRIORITY) + .supplier(CondScalesWithDifficulty::new) + .addPatterns("%damagesources% ((does|do) scale|scales) damage with difficulty", + "%damagesources% (do not|don't|does not|doesn't) scale damage with difficulty", + "%damagesources%'[s] damage ((does|do) scale|scales) with difficulty", + "%damagesources%'[s] damage (do not|don't|does not|doesn't) scale with difficulty") + .build(); } @Override diff --git a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/CondWasIndirect.java b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/CondWasIndirect.java index c9ee8dafd92..a26cff2b502 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/CondWasIndirect.java +++ b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/CondWasIndirect.java @@ -11,6 +11,7 @@ import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; import org.skriptlang.skript.bukkit.damagesource.DamageSourceExperimentSyntax; +import org.skriptlang.skript.registration.SyntaxInfo; @Name("Damage Source - Was Indirectly Caused") @Description({ @@ -24,14 +25,15 @@ """) @Since("2.12") @RequiredPlugins("Minecraft 1.20.4+") -@SuppressWarnings("UnstableApiUsage") public class CondWasIndirect extends PropertyCondition implements DamageSourceExperimentSyntax { - static { - Skript.registerCondition(CondWasIndirect.class, ConditionType.PROPERTY, - "%damagesources% (was|were) ([:in]directly caused|caused [:in]directly)", - "%damagesources% (was not|wasn't|were not|weren't) ([:in]directly caused|caused [:in]directly)" - ); + public static SyntaxInfo info() { + return SyntaxInfo.builder(CondWasIndirect.class) + .priority(DEFAULT_PRIORITY) + .supplier(CondWasIndirect::new) + .addPatterns("%damagesources% (was|were) ([:in]directly caused|caused [:in]directly)", + "%damagesources% (was not|wasn't|were not|weren't) ([:in]directly caused|caused [:in]directly)") + .build(); } private boolean indirect; diff --git a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprCausingEntity.java b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprCausingEntity.java index 46cbac41fec..69614484094 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprCausingEntity.java +++ b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprCausingEntity.java @@ -14,6 +14,8 @@ import org.jetbrains.annotations.Nullable; import org.skriptlang.skript.bukkit.damagesource.DamageSourceExperimentSyntax; import org.skriptlang.skript.bukkit.damagesource.elements.ExprSecDamageSource.DamageSourceSectionEvent; +import org.skriptlang.skript.registration.DefaultSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxInfo; @Name("Damage Source - Causing Entity") @Description({ @@ -37,8 +39,10 @@ set the damage location to location(0, 0, 10) @RequiredPlugins("Minecraft 1.20.4+") public class ExprCausingEntity extends SimplePropertyExpression implements DamageSourceExperimentSyntax { - static { - registerDefault(ExprCausingEntity.class, Entity.class, "(causing|responsible) entity", "damagesources"); + public static SyntaxInfo.Expression info() { + return infoBuilder(ExprCausingEntity.class, Entity.class, "(causing|responsible) entity", "damagesources", true) + .supplier(ExprCausingEntity::new) + .build(); } private boolean isEvent; diff --git a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprCreatedDamageSource.java b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprCreatedDamageSource.java index 6efbec5f8c2..496b7ee7e5a 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprCreatedDamageSource.java +++ b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprCreatedDamageSource.java @@ -7,6 +7,8 @@ import org.bukkit.damage.DamageSource; import org.bukkit.event.Event; import org.skriptlang.skript.bukkit.damagesource.elements.ExprSecDamageSource.DamageSourceSectionEvent; +import org.skriptlang.skript.registration.DefaultSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxInfo; @Name("Created Damage Source") @Description("Get the created damage source being created/modified in a 'custom damage source' section.") @@ -16,11 +18,12 @@ """) @Since("2.12") @RequiredPlugins("Minecraft 1.20.4+") -@SuppressWarnings("UnstableApiUsage") public class ExprCreatedDamageSource extends EventValueExpression implements EventRestrictedSyntax { - static { - register(ExprCreatedDamageSource.class, DamageSource.class, "created damage source"); + public static SyntaxInfo.Expression info() { + return infoBuilder(ExprCreatedDamageSource.class, DamageSource.class, "created damage source") + .supplier(ExprCreatedDamageSource::new) + .build(); } public ExprCreatedDamageSource() { diff --git a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprDamageLocation.java b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprDamageLocation.java index 8ef78b71d15..3e7c01914aa 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprDamageLocation.java +++ b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprDamageLocation.java @@ -14,6 +14,8 @@ import org.jetbrains.annotations.Nullable; import org.skriptlang.skript.bukkit.damagesource.DamageSourceExperimentSyntax; import org.skriptlang.skript.bukkit.damagesource.elements.ExprSecDamageSource.DamageSourceSectionEvent; +import org.skriptlang.skript.registration.DefaultSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxInfo; @Name("Damage Source - Damage Location") @Description({ @@ -34,11 +36,12 @@ set the damage location to location(0, 0, 10) """) @Since("2.12") @RequiredPlugins("Minecraft 1.20.4+") -@SuppressWarnings("UnstableApiUsage") public class ExprDamageLocation extends SimplePropertyExpression implements DamageSourceExperimentSyntax { - static { - registerDefault(ExprDamageLocation.class, Location.class, "damage location", "damagesources"); + public static SyntaxInfo.Expression info() { + return infoBuilder(ExprDamageLocation.class, Location.class, "damage location", "damagesources", true) + .supplier(ExprDamageLocation::new) + .build(); } private boolean isEvent; diff --git a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprDamageType.java b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprDamageType.java index 54171a3c407..f8ab8ba69e3 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprDamageType.java +++ b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprDamageType.java @@ -14,6 +14,8 @@ import org.jetbrains.annotations.Nullable; import org.skriptlang.skript.bukkit.damagesource.DamageSourceExperimentSyntax; import org.skriptlang.skript.bukkit.damagesource.elements.ExprSecDamageSource.DamageSourceSectionEvent; +import org.skriptlang.skript.registration.DefaultSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxInfo; @Name("Damage Source - Damage Type") @Description({ @@ -34,11 +36,12 @@ set the damage location to location(0, 0, 10) """) @Since("2.12") @RequiredPlugins("Minecraft 1.20.4+") -@SuppressWarnings("UnstableApiUsage") public class ExprDamageType extends SimplePropertyExpression implements DamageSourceExperimentSyntax { - static { - registerDefault(ExprDamageType.class, DamageType.class, "damage type", "damagesources"); + public static SyntaxInfo.Expression info() { + return infoBuilder(ExprDamageType.class, DamageType.class, "damage type", "damagesources", true) + .supplier(ExprDamageType::new) + .build(); } private boolean isEvent; diff --git a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprDirectEntity.java b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprDirectEntity.java index 9561eba3360..5f413b19e40 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprDirectEntity.java +++ b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprDirectEntity.java @@ -9,11 +9,14 @@ import ch.njol.util.Kleenean; import ch.njol.util.coll.CollectionUtils; import org.bukkit.damage.DamageSource; +import org.bukkit.damage.DamageType; import org.bukkit.entity.Entity; import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; import org.skriptlang.skript.bukkit.damagesource.DamageSourceExperimentSyntax; import org.skriptlang.skript.bukkit.damagesource.elements.ExprSecDamageSource.DamageSourceSectionEvent; +import org.skriptlang.skript.registration.DefaultSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxInfo; @Name("Damage Source - Direct Entity") @Description({ @@ -35,11 +38,12 @@ set the damage location to location(0, 0, 10) """) @Since("2.12") @RequiredPlugins("Minecraft 1.20.4+") -@SuppressWarnings("UnstableApiUsage") public class ExprDirectEntity extends SimplePropertyExpression implements DamageSourceExperimentSyntax { - static { - registerDefault(ExprDirectEntity.class, Entity.class, "direct entity", "damagesources"); + public static SyntaxInfo.Expression info() { + return infoBuilder(ExprDirectEntity.class, Entity.class, "direct entity", "damagesources", true) + .supplier(ExprDirectEntity::new) + .build(); } private boolean isEvent; diff --git a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprFoodExhaustion.java b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprFoodExhaustion.java index 11752bb491f..243725cacf1 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprFoodExhaustion.java +++ b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprFoodExhaustion.java @@ -5,6 +5,8 @@ import org.bukkit.damage.DamageSource; import org.jetbrains.annotations.Nullable; import org.skriptlang.skript.bukkit.damagesource.DamageSourceExperimentSyntax; +import org.skriptlang.skript.registration.DefaultSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxInfo; @Name("Damage Source - Food Exhaustion") @Description("The amount of hunger exhaustion caused by a damage source.") @@ -14,11 +16,12 @@ """) @Since("2.12") @RequiredPlugins("Minecraft 1.20.4+") -@SuppressWarnings("UnstableApiUsage") public class ExprFoodExhaustion extends SimplePropertyExpression implements DamageSourceExperimentSyntax { - static { - registerDefault(ExprFoodExhaustion.class, Float.class, "food exhaustion", "damagesources"); + public static SyntaxInfo.Expression info() { + return infoBuilder(ExprFoodExhaustion.class, Float.class, "food exhaustion", "damagesources", true) + .supplier(ExprFoodExhaustion::new) + .build(); } @Override diff --git a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprSecDamageSource.java b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprSecDamageSource.java index 6c7168a3788..51d7051623b 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprSecDamageSource.java +++ b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprSecDamageSource.java @@ -26,6 +26,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.skriptlang.skript.bukkit.damagesource.DamageSourceExperimentSyntax; +import org.skriptlang.skript.registration.DefaultSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxInfo; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; @@ -80,10 +82,13 @@ public DamageSourceSectionEvent() {} } } - static { - Skript.registerExpression(ExprSecDamageSource.class, DamageSource.class, ExpressionType.COMBINED, - "[a] custom damage source [(with|using) [the|a] [damage type [of]] %-damagetype%]"); + public static SyntaxInfo.Expression info() { EventValues.registerEventValue(DamageSourceSectionEvent.class, DamageSource.class, DamageSourceSectionEvent::buildDamageSource); + + return SyntaxInfo.Expression.builder(ExprSecDamageSource.class, DamageSource.class) + .supplier(ExprSecDamageSource::new) + .addPatterns("[a] custom damage source [(with|using) [the|a] [damage type [of]] %-damagetype%]") + .build(); } private @Nullable Expression damageType; diff --git a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprSourceLocation.java b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprSourceLocation.java index 291e649a7e7..752cb20e4e0 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprSourceLocation.java +++ b/src/main/java/org/skriptlang/skript/bukkit/damagesource/elements/ExprSourceLocation.java @@ -6,6 +6,8 @@ import org.bukkit.damage.DamageSource; import org.jetbrains.annotations.Nullable; import org.skriptlang.skript.bukkit.damagesource.DamageSourceExperimentSyntax; +import org.skriptlang.skript.registration.DefaultSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxInfo; @Name("Damage Source - Source Location") @Description({ @@ -20,11 +22,12 @@ """) @Since("2.12") @RequiredPlugins("Minecraft 1.20.4+") -@SuppressWarnings("UnstableApiUsage") public class ExprSourceLocation extends SimplePropertyExpression implements DamageSourceExperimentSyntax { - static { - registerDefault(ExprSourceLocation.class, Location.class, "source location", "damagesources"); + public static SyntaxInfo.Expression info() { + return infoBuilder(ExprSourceLocation.class, Location.class, "source location", "damagesources", true) + .supplier(ExprSourceLocation::new) + .build(); } @Override diff --git a/src/main/java/org/skriptlang/skript/registration/SyntaxOrigin.java b/src/main/java/org/skriptlang/skript/registration/SyntaxOrigin.java index b5e8aa9d552..5a901e00cd1 100644 --- a/src/main/java/org/skriptlang/skript/registration/SyntaxOrigin.java +++ b/src/main/java/org/skriptlang/skript/registration/SyntaxOrigin.java @@ -2,6 +2,7 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; +import org.skriptlang.skript.addon.AddonModule; import org.skriptlang.skript.addon.SkriptAddon; /** @@ -52,6 +53,57 @@ public SkriptAddon addon() { } + /** + * Constructs a syntax origin from an addon and module. + * @param addon The addon to construct this origin from. + * @param module The module to include in this origin. + * @return An origin pointing to the provided addon and module. + */ + @Contract("_, _ -> new") + static SyntaxOrigin of(SkriptAddon addon, AddonModule module) { + return new ModuleOrigin(addon, module); + } + + /** + * An origin describing the addon and module a syntax has originated from. + * @see SyntaxOrigin#of(SkriptAddon, AddonModule) + */ + final class ModuleOrigin implements SyntaxOrigin { + + private final SkriptAddon addon; + private final AddonModule module; + + private ModuleOrigin(SkriptAddon addon, AddonModule module) { + this.addon = addon.unmodifiableView(); + this.module = module; + } + + /** + * @return A string representing the name of the addon this origin describes. + * Equivalent to {@link SkriptAddon#name()}. + */ + @Override + public String name() { + return addon.name(); + } + + /** + * @return An unmodifiable view of the addon this origin describes. + * @see SkriptAddon#unmodifiableView() + */ + public SkriptAddon addon() { + return addon; + } + + /** + * @return The module used for registering this element. + */ + public AddonModule module() { + return module; + } + + } + /** * @return A string representing this origin. */