removed static reference to server in annotation parser
This commit is contained in:
1 parent
75d94b0570
commit
aea76d9764
10 files changed
+64
-40
No files matched your search
@@ -20,7 +20,6 @@ import org.apache.commons.lang3.ClassUtils;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
|
||||
import carpet.CarpetExtension;
|
||||
import carpet.script.Context;
|
||||
import carpet.script.Expression;
|
||||
import carpet.script.Fluff.AbstractLazyFunction;
|
||||
@@ -85,7 +84,7 @@ public final class AnnotationParser
|
||||
* <p>Parses a given {@link Class} and registers its annotated methods, the ones with the {@link ScarpetFunction} annotation,
|
||||
* to be used in the Scarpet language.</p>
|
||||
*
|
||||
* <p><b>Only call this method once per class per lifetime of the JVM!</b> (for example, at {@link CarpetExtension#onGameStarted()} or
|
||||
* <p><b>Only call this method once per class per lifetime of the JVM!</b> (for example, at {@link carpet.CarpetExtension#onGameStarted()} or
|
||||
* {@link ModInitializer#onInitialize()}).</p>
|
||||
*
|
||||
* <p>There is a set of requirements for the class and its methods:</p>
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import carpet.script.Context;
|
||||
import carpet.script.value.ListValue;
|
||||
import carpet.script.value.Value;
|
||||
|
||||
@@ -32,17 +33,17 @@ final class ListConverter<T> implements ValueConverter<List<T>>
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> convert(final Value value)
|
||||
public List<T> convert(final Value value, final Context context)
|
||||
{
|
||||
return value instanceof ListValue ? convertListValue((ListValue) value) : allowSingletonCreation ? convertSingleton(value) : null;
|
||||
return value instanceof ListValue ? convertListValue((ListValue) value, context) : allowSingletonCreation ? convertSingleton(value, context) : null;
|
||||
}
|
||||
|
||||
private List<T> convertListValue(final ListValue values)
|
||||
private List<T> convertListValue(final ListValue values, final Context context)
|
||||
{
|
||||
final List<T> list = new ArrayList<>(values.getItems().size());
|
||||
for (final Value value : values)
|
||||
{
|
||||
final T converted = itemConverter.convert(value);
|
||||
final T converted = itemConverter.convert(value, context);
|
||||
if (converted == null)
|
||||
{
|
||||
return null;
|
||||
@@ -52,9 +53,9 @@ final class ListConverter<T> implements ValueConverter<List<T>>
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<T> convertSingleton(final Value val)
|
||||
private List<T> convertSingleton(final Value val, final Context context)
|
||||
{
|
||||
final T converted = itemConverter.convert(val);
|
||||
final T converted = itemConverter.convert(val, context);
|
||||
if (converted == null)
|
||||
{
|
||||
return null;
|
||||
|
||||
@@ -276,7 +276,7 @@ public interface Locator
|
||||
private abstract static class AbstractLocator<R> implements ValueConverter<R>, Locator
|
||||
{
|
||||
@Override
|
||||
public R convert(final Value value)
|
||||
public R convert(final Value value, final Context context)
|
||||
{
|
||||
throw new UnsupportedOperationException("Cannot call a locator in a parameter that doesn't contain a context!");
|
||||
}
|
||||
|
||||
@@ -37,15 +37,15 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<K, V> convert(final Value value)
|
||||
public Map<K, V> convert(final Value value, final Context context)
|
||||
{
|
||||
final Map<K, V> result = new HashMap<>();
|
||||
if (value instanceof MapValue)
|
||||
{
|
||||
for (final Entry<Value, Value> entry : ((MapValue) value).getMap().entrySet())
|
||||
{
|
||||
final K key = keyConverter.convert(entry.getKey());
|
||||
final V val = valueConverter.convert(entry.getValue());
|
||||
final K key = keyConverter.convert(entry.getKey(), context);
|
||||
final V val = valueConverter.convert(entry.getValue(), context);
|
||||
if (key == null || val == null)
|
||||
{
|
||||
return null;
|
||||
@@ -105,14 +105,14 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<K, V> convert(final Value value) {
|
||||
return value instanceof MapValue ? super.convert(value)
|
||||
: value instanceof ListValue ? convertList(((ListValue)value).getItems())
|
||||
public Map<K, V> convert(final Value value, final Context context) {
|
||||
return value instanceof MapValue ? super.convert(value, context)
|
||||
: value instanceof ListValue ? convertList(((ListValue)value).getItems(), context)
|
||||
: null; // Multiparam mode can only be used in evalAndConvert
|
||||
}
|
||||
|
||||
|
||||
private Map<K, V> convertList(final List<Value> valueList)
|
||||
private Map<K, V> convertList(final List<Value> valueList, final Context context)
|
||||
{
|
||||
if (valueList.size() % 2 == 1)
|
||||
{
|
||||
@@ -122,8 +122,8 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
||||
final Iterator<Value> val = valueList.iterator();
|
||||
while (val.hasNext())
|
||||
{
|
||||
final K key = keyConverter.convert(val.next());
|
||||
final V value = valueConverter.convert(val.next());
|
||||
final K key = keyConverter.convert(val.next(), context);
|
||||
final V value = valueConverter.convert(val.next(), context);
|
||||
if (key == null || value == null)
|
||||
{
|
||||
return null;
|
||||
@@ -143,11 +143,11 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
||||
final Value val = valueIterator.next();
|
||||
if (!acceptMultiParam || val instanceof MapValue || (val instanceof ListValue && !(keyConverter instanceof ListConverter)))
|
||||
{
|
||||
return convert(val); // @KeyValuePairs Map<List<Something>, Boolean> will not support list consumption
|
||||
return convert(val, context); // @KeyValuePairs Map<List<Something>, Boolean> will not support list consumption
|
||||
}
|
||||
|
||||
final Map<K, V> map = new HashMap<>();
|
||||
K key = keyConverter.convert(val); //First pair is manual since we got it to check for a different conversion mode
|
||||
K key = keyConverter.convert(val, context); //First pair is manual since we got it to check for a different conversion mode
|
||||
V value = valueConverter.checkAndConvert(valueIterator, context, theLazyT);
|
||||
if (key == null || value == null)
|
||||
{
|
||||
|
||||
@@ -50,13 +50,13 @@ final class OptionalConverter<R> implements ValueConverter<Optional<R>>
|
||||
* {@link #checkAndConvert(Iterator, Context, Context.Type)} and is only used as a fallback in types that don't support it.
|
||||
*/
|
||||
@Override
|
||||
public Optional<R> convert(final Value value)
|
||||
public Optional<R> convert(final Value value, final Context context)
|
||||
{
|
||||
if (value.isNull())
|
||||
{
|
||||
return Optional.empty();
|
||||
}
|
||||
final R converted = typeConverter.convert(value);
|
||||
final R converted = typeConverter.convert(value, context);
|
||||
if (converted == null)
|
||||
{
|
||||
return null;
|
||||
|
||||
@@ -6,7 +6,6 @@ import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.GlobalPos;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
@@ -148,7 +148,7 @@ public interface Param
|
||||
@Override public String getTypeName() { return null; }
|
||||
|
||||
@Override
|
||||
public Context convert(final Value value)
|
||||
public Context convert(final Value value, final Context context)
|
||||
{
|
||||
throw new UnsupportedOperationException("Called convert() with Value in Context Provider converter, where only checkAndConvert is supported");
|
||||
}
|
||||
@@ -175,7 +175,7 @@ public interface Param
|
||||
@Override public String getTypeName() { return null; }
|
||||
|
||||
@Override
|
||||
public Context.Type convert(final Value value)
|
||||
public Context.Type convert(final Value value, final Context context)
|
||||
{
|
||||
throw new UnsupportedOperationException("Called convert() with a Value in TheLazyT Provider, where only checkAndConvert is supported");
|
||||
}
|
||||
|
||||
@@ -2,12 +2,15 @@ package carpet.script.annotation;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
import carpet.script.CarpetContext;
|
||||
import carpet.script.Context;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import carpet.CarpetServer;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import carpet.script.value.EntityValue;
|
||||
import carpet.script.value.FormattedTextValue;
|
||||
@@ -31,9 +34,9 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
|
||||
private static final Map<Class<?>, SimpleTypeConverter<? extends Value, ?>> byResult = new HashMap<>();
|
||||
static
|
||||
{
|
||||
registerType(Value.class, ServerPlayer.class, val -> EntityValue.getPlayerByValue(CarpetServer.minecraft_server, val), "online player");
|
||||
registerType(Value.class, ServerPlayer.class, (v, c) -> EntityValue.getPlayerByValue(((CarpetContext)c).server(), v), "online player");
|
||||
registerType(EntityValue.class, Entity.class, EntityValue::getEntity, "entity");
|
||||
registerType(Value.class, Level.class, val -> ValueConversions.dimFromValue(val, CarpetServer.minecraft_server), "dimension");
|
||||
registerType(Value.class, Level.class, (v, c) -> ValueConversions.dimFromValue(v, ((CarpetContext)c).server()), "dimension");
|
||||
registerType(Value.class, Component.class, FormattedTextValue::getTextByValue, "text");
|
||||
registerType(Value.class, String.class, Value::getString, "string"); // Check out @Param.Strict for more specific types
|
||||
|
||||
@@ -44,7 +47,7 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
|
||||
registerType(Value.class, Boolean.class, Value::getBoolean, "boolean"); // Check out @Param.Strict for more specific types
|
||||
}
|
||||
|
||||
private final Function<T, R> converter;
|
||||
private final BiFunction<T, Context, R> converter;
|
||||
private final Class<T> valueClass;
|
||||
private final String typeName;
|
||||
|
||||
@@ -58,7 +61,7 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
|
||||
* @param inputType The required type for the input {@link Value}
|
||||
* @param converter The function to convert an instance of inputType into R.
|
||||
*/
|
||||
public SimpleTypeConverter(final Class<T> inputType, final Function<T, R> converter, final String typeName)
|
||||
public SimpleTypeConverter(final Class<T> inputType, final BiFunction<T, Context, R> converter, final String typeName)
|
||||
{
|
||||
super();
|
||||
this.converter = converter;
|
||||
@@ -66,6 +69,14 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
|
||||
this.typeName = typeName;
|
||||
}
|
||||
|
||||
public SimpleTypeConverter(final Class<T> inputType, final Function<T, R> converter, final String typeName)
|
||||
{
|
||||
super();
|
||||
this.converter = (v, c) -> converter.apply(v);
|
||||
this.valueClass = inputType;
|
||||
this.typeName = typeName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName()
|
||||
{
|
||||
@@ -87,9 +98,9 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked") // more than checked. not using class.cast because then "method is too big" for inlining, because javac is useless
|
||||
public R convert(final Value value) // and adds millions of casts. This one is even removed
|
||||
public R convert(final Value value, final Context context) // and adds millions of casts. This one is even removed
|
||||
{
|
||||
return valueClass.isInstance(value) ? converter.apply((T)value) : null;
|
||||
return valueClass.isInstance(value) ? converter.apply((T)value, context) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,15 +110,21 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
|
||||
* @param <R> The type of the resulting object
|
||||
* @param requiredInputType The {@link Class} of {@code <T>}
|
||||
* @param outputType The {@link Class} of {@code <R>>}
|
||||
* @param converter A function that converts from the given {@link Value} subtype to the given type. Should ideally return {@code null}
|
||||
* @param converter A bi function that converts from the given {@link Value} subtype to the given type. Should ideally return {@code null}
|
||||
* when given {@link Value} cannot be converted to the {@code <R>}, to follow the {@link ValueConverter} contract, but it
|
||||
* can also throw an {@link InternalExpressionException} by itself if really necessary.
|
||||
* @param typeName The name of the type, following the conventions of {@link ValueConverter#getTypeName()}
|
||||
*/
|
||||
public static <T extends Value, R> void registerType(final Class<T> requiredInputType, final Class<R> outputType,
|
||||
final Function<T, R> converter, final String typeName)
|
||||
final BiFunction<T, Context, R> converter, final String typeName)
|
||||
{
|
||||
final SimpleTypeConverter<T, R> type = new SimpleTypeConverter<>(requiredInputType, converter, typeName);
|
||||
byResult.put(outputType, type);
|
||||
}
|
||||
|
||||
public static <T extends Value, R> void registerType(final Class<T> requiredInputType, final Class<R> outputType,
|
||||
final Function<T, R> converter, final String typeName)
|
||||
{
|
||||
registerType(requiredInputType, outputType, (val, ctx) -> converter.apply(val), typeName);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package carpet.script.annotation;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import carpet.script.Context;
|
||||
import carpet.script.value.AbstractListValue;
|
||||
import carpet.script.value.BlockValue;
|
||||
import carpet.script.value.BooleanValue;
|
||||
@@ -79,7 +80,7 @@ public final class ValueCaster<R> implements ValueConverter<R> // R always exten
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked") // more than checked, see SimpleTypeConverter#converter for reasoning
|
||||
public R convert(final Value value)
|
||||
public R convert(final Value value, final Context context)
|
||||
{
|
||||
if (!outputType.isInstance(value))
|
||||
{
|
||||
|
||||
@@ -50,6 +50,7 @@ public interface ValueConverter<R>
|
||||
* trying to convert to anything else, where it would be recommended to tell the user the name of the final type instead.</p>
|
||||
*
|
||||
* @param value The {@link Value} to convert
|
||||
* @param context
|
||||
* @return The converted value, or {@code null} if the conversion failed in the process
|
||||
* @apiNote <p>While most implementations of this method should and will return the type from this method, implementations that <b>require</b>
|
||||
* parameters from {@link #checkAndConvert(Iterator, Context, Context.Type)} or that require multiple parameters may decide to throw
|
||||
@@ -59,10 +60,16 @@ public interface ValueConverter<R>
|
||||
* <p>Implementations can also provide different implementations for this and {@link #checkAndConvert(Iterator, Context, Context.Type)}, in case
|
||||
* they can support it in some situations that can't be used else, such as inside of lists or maps, although they should try to provide
|
||||
* in {@link #checkAndConvert(Iterator, Context, Context.Type)} at least the same conversion as the one from this method.</p>
|
||||
* <p>Even with the above reasons, {@link ValueConverter} users should try to implement {@link #convert(Value)} whenever possible instead of
|
||||
* <p>Even with the above reasons, {@link ValueConverter} users should try to implement {@link #convert(Value, Context)} whenever possible instead of
|
||||
* {@link #checkAndConvert(Iterator, Context, Context.Type)}, since it allows its usage in generics of lists and maps.</p>
|
||||
*/
|
||||
@Nullable R convert(Value value);
|
||||
@Nullable R convert(Value value, final Context context);
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
default R convert(final Value value)
|
||||
{
|
||||
return convert(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns whether this {@link ValueConverter} consumes a variable number of elements from the {@link Iterator} passed to it via
|
||||
@@ -176,17 +183,17 @@ public interface ValueConverter<R>
|
||||
* providers like {@link Context}. <p>Implementations can also use more than a single parameter when being called with this function,
|
||||
* but in such case they must implement {@link #valueConsumption()} to return how many parameters do they consume at minimum, and, if
|
||||
* they may consume variable arguments, implement {@link #consumesVariableArgs()}</p> <p>This method holds the same nullability
|
||||
* constraints as {@link #convert(Value)}</p>
|
||||
* constraints as {@link #convert(Value, Context)}</p>
|
||||
* @param valueIterator An {@link Iterator} holding the {@link Value} to convert in next position
|
||||
* @param context The {@link Context} this function has been called with. This was used when this passed lazy values instead in order to
|
||||
* evaluate, now it's used to get the context
|
||||
* @param contextType The {@link Context.Type} that the original function was called with
|
||||
* @return The next {@link Value} (s) converted to the type {@code <R>} of this {@link ValueConverter}
|
||||
* @implNote This method's default implementation runs the {@link #convert(Value)} function in the next {@link Value} ignoring {@link Context} and
|
||||
* @implNote This method's default implementation runs the {@link #convert(Value, Context)} function in the next {@link Value} ignoring {@link Context} and
|
||||
* {@code theLazyT}.
|
||||
*/
|
||||
default R checkAndConvert(final Iterator<Value> valueIterator, final Context context, final Context.Type contextType)
|
||||
{
|
||||
return !valueIterator.hasNext() ? null : convert(valueIterator.next());
|
||||
return !valueIterator.hasNext() ? null : convert(valueIterator.next(), context);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user