From adf15f5fdd4e5bb082f22e7fbd0d1adc3c947e23 Mon Sep 17 00:00:00 2001 From: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> Date: Wed, 15 Nov 2023 08:24:30 -0700 Subject: [PATCH 1/2] Update SectionConfiguration to use optionals --- .../lang/entries/SectionConfiguration.java | 51 +++++++++++-------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/src/main/java/io/github/syst3ms/skriptparser/lang/entries/SectionConfiguration.java b/src/main/java/io/github/syst3ms/skriptparser/lang/entries/SectionConfiguration.java index 81c61754..c802749a 100644 --- a/src/main/java/io/github/syst3ms/skriptparser/lang/entries/SectionConfiguration.java +++ b/src/main/java/io/github/syst3ms/skriptparser/lang/entries/SectionConfiguration.java @@ -12,6 +12,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; /** * The SectionConfiguration class can be used to create simple and efficient data sections @@ -34,12 +35,14 @@ * */ public class SectionConfiguration { + + private final Map data = new HashMap<>(); + private final List entries; + @Nullable private CodeSection parent; - private final List entries; - private final Map data = new HashMap<>(); - private boolean loaded = false; - + private boolean loaded; + private SectionConfiguration(List entries) { this.entries = entries; } @@ -49,6 +52,7 @@ private SectionConfiguration(List entries) { * a FileSection instance. This method should be called only once and will throw an error if attempting * to load the configuration multiple times. The default use-case would be to load the configuration inside * CodeSection's {@link CodeSection#loadSection(FileSection, ParserState, SkriptLogger) load} method. + * * @param parent the parent section * @param section the file section * @param parserState the parse state @@ -64,9 +68,8 @@ public boolean loadConfiguration(@Nullable CodeSection parent, FileSection secti outer: for (var entry : entries) { - for (var el : section.getElements()) { - logger.setLine(el.getLine() - 1); - + for (var element : section.getElements()) { + logger.setLine(element.getLine() - 1); if (logger.hasError()) { /* * If the execution of 'loadEntry' caused errors, it means that we @@ -78,9 +81,9 @@ public boolean loadConfiguration(@Nullable CodeSection parent, FileSection secti successful = false; continue outer; } - if (el instanceof VoidElement) + if (element instanceof VoidElement) continue; - if (entry.loadEntry(this, el, parserState, logger)) + if (entry.loadEntry(this, element, parserState, logger)) continue outer; } if (entry.isOptional()) @@ -115,6 +118,7 @@ public Map getData() { return data; } + @Nullable public Object getValue(String key) { return data.get(key); } @@ -124,32 +128,37 @@ public Object getValue(String key) { * This can only be used when you register your option as a {@link Builder#addLiteral(String, Class) literal}, * otherwise, the option will likely be parsed as a String and throw an exception. * Options that allow literal lists are saved as an array. - * @param key the key - * @param cls the class to cast to - * @return the value cast to the given class - * @param the type of the value + * + * @param key the key of the node. + * @param cls the class to cast to. + * @return the value cast to the given class. + * @param the type of the return value. */ @SuppressWarnings("unchecked") - public T getValue(String key, Class cls) { + public Optional getValue(String key, Class cls) { var result = data.get(key); + if (result == null) + return Optional.empty(); if (result.getClass() == String.class && result.getClass() != cls) throw new UnsupportedOperationException("The key '" + key + "' was not registered as a literal, was parsed as a String and can, therefore, not be cast to " + cls.getName()); - return (T) result; + return Optional.of((T) result); } - public String getString(String key) { + @Nullable + public Optional getString(String key) { return getValue(key, String.class); } - public String[] getStringList(String key) { + public Optional getStringList(String key) { return getValue(key, String[].class); } - public CodeSection getSection(String key) { + public Optional getSection(String key) { return getValue(key, CodeSection.class); } - + public static class Builder { + private final List entries = new ArrayList<>(); public Builder addKey(String key) { @@ -195,5 +204,7 @@ public Builder addLoader(EntryLoader loader) { public SectionConfiguration build() { return new SectionConfiguration(entries); } + } -} \ No newline at end of file + +} From 1666e962d6908ee9f58f7db89b483aa0b95494a1 Mon Sep 17 00:00:00 2001 From: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> Date: Wed, 15 Nov 2023 08:29:28 -0700 Subject: [PATCH 2/2] Update LiteralLoader.java --- .../lang/entries/LiteralLoader.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/github/syst3ms/skriptparser/lang/entries/LiteralLoader.java b/src/main/java/io/github/syst3ms/skriptparser/lang/entries/LiteralLoader.java index c5429c02..37c5293a 100644 --- a/src/main/java/io/github/syst3ms/skriptparser/lang/entries/LiteralLoader.java +++ b/src/main/java/io/github/syst3ms/skriptparser/lang/entries/LiteralLoader.java @@ -10,6 +10,7 @@ import java.util.List; public class LiteralLoader extends OptionLoader { + private final Class typeClass; public LiteralLoader(String key, Class typeClass, boolean multiple, boolean optional) { @@ -38,7 +39,13 @@ public boolean loadEntry(SectionConfiguration config, FileElement element, Parse if (isMultiple()) { List data = new ArrayList<>(); boolean successful = true; - for (var value : config.getStringList(key)) { + + var list = config.getStringList(key); + if (!list.isPresent()) { + logger.error("List at key '" + key + "' does not exist.", ErrorType.SEMANTIC_ERROR); + return false; + } + for (var value : list.get()) { var result = parser.apply(value); if (result == null) { // With the logic that errors get skipped, we will allow the other values to be parsed. @@ -52,7 +59,12 @@ public boolean loadEntry(SectionConfiguration config, FileElement element, Parse config.getData().put(key, data.toArray()); return successful; } else { - var result = parser.apply(config.getString(key)); + var value = config.getString(key); + if (!value.isPresent()) { + logger.error("Key '" + key + "' does not exist.", ErrorType.SEMANTIC_ERROR); + return false; + } + var result = parser.apply(value.get()); // We don't want this data to linger if an error occurs config.getData().remove(key); if (result == null) { @@ -62,5 +74,7 @@ public boolean loadEntry(SectionConfiguration config, FileElement element, Parse config.getData().put(key, result); return true; } + } + }