warning cleanup
This commit is contained in:
1 parent
5ab4a9e442
commit
277872b33c
106 files changed
+4495
-4345
No files matched your search
@@ -104,10 +104,10 @@ public final class AnnotationParser
|
||||
* @see ScarpetFunction
|
||||
* @param clazz The class to parse
|
||||
*/
|
||||
public static void parseFunctionClass(final Class<?> clazz)
|
||||
public static void parseFunctionClass(Class<?> clazz)
|
||||
{
|
||||
// Only try to instantiate or require concrete classes if there are non-static annotated methods
|
||||
final Supplier<Object> instanceSupplier = Suppliers.memoize(() -> {
|
||||
Supplier<Object> instanceSupplier = Suppliers.memoize(() -> {
|
||||
if (Modifier.isAbstract(clazz.getModifiers()))
|
||||
{
|
||||
throw new IllegalArgumentException("Function class must be concrete to support non-static methods! Class: " + clazz.getSimpleName());
|
||||
@@ -116,14 +116,14 @@ public final class AnnotationParser
|
||||
{
|
||||
return clazz.getConstructor().newInstance();
|
||||
}
|
||||
catch (final ReflectiveOperationException e)
|
||||
catch (ReflectiveOperationException e)
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"Couldn't create instance of given " + clazz + ". This is needed for non-static methods. Make sure default constructor is available", e);
|
||||
}
|
||||
});
|
||||
final Method[] methodz = clazz.getDeclaredMethods();
|
||||
for (final Method method : methodz)
|
||||
Method[] methodz = clazz.getDeclaredMethods();
|
||||
for (Method method : methodz)
|
||||
{
|
||||
if (!method.isAnnotationPresent(ScarpetFunction.class))
|
||||
{
|
||||
@@ -135,7 +135,7 @@ public final class AnnotationParser
|
||||
throw new IllegalArgumentException("Annotated method '" + method.getName() +"', provided in '"+clazz+"' must not declare checked exceptions");
|
||||
}
|
||||
|
||||
final ParsedFunction function = new ParsedFunction(method, clazz, instanceSupplier);
|
||||
ParsedFunction function = new ParsedFunction(method, clazz, instanceSupplier);
|
||||
functionList.add(function);
|
||||
}
|
||||
}
|
||||
@@ -146,9 +146,9 @@ public final class AnnotationParser
|
||||
*
|
||||
* @param expr The expression to add every function to
|
||||
*/
|
||||
public static void apply(final Expression expr)
|
||||
public static void apply(Expression expr)
|
||||
{
|
||||
for (final ParsedFunction function : functionList)
|
||||
for (ParsedFunction function : functionList)
|
||||
{
|
||||
expr.addLazyFunction(function.name, function.scarpetParamCount, function);
|
||||
}
|
||||
@@ -171,52 +171,52 @@ public final class AnnotationParser
|
||||
private final int scarpetParamCount;
|
||||
private final Context.Type contextType;
|
||||
|
||||
private ParsedFunction(final Method method, final Class<?> originClass, final Supplier<Object> instance)
|
||||
private ParsedFunction(Method method, Class<?> originClass, Supplier<Object> instance)
|
||||
{
|
||||
this.name = method.getName();
|
||||
this.isMethodVarArgs = method.isVarArgs();
|
||||
this.methodParamCount = method.getParameterCount();
|
||||
|
||||
final Parameter[] methodParameters = method.getParameters();
|
||||
Parameter[] methodParameters = method.getParameters();
|
||||
this.valueConverters = new ValueConverter[isMethodVarArgs ? methodParamCount - 1 : methodParamCount];
|
||||
for (int i = 0; i < this.methodParamCount; i++)
|
||||
{
|
||||
final Parameter param = methodParameters[i];
|
||||
Parameter param = methodParameters[i];
|
||||
if (!isMethodVarArgs || i != this.methodParamCount - 1) // Varargs converter is separate
|
||||
{
|
||||
this.valueConverters[i] = ValueConverter.fromAnnotatedType(param.getAnnotatedType());
|
||||
}
|
||||
}
|
||||
final Class<?> originalVarArgsType = isMethodVarArgs ? methodParameters[methodParamCount - 1].getType().getComponentType() : null;
|
||||
Class<?> originalVarArgsType = isMethodVarArgs ? methodParameters[methodParamCount - 1].getType().getComponentType() : null;
|
||||
this.varArgsType = ClassUtils.primitiveToWrapper(originalVarArgsType); // Primitive array cannot be cast to Obj[]
|
||||
this.primitiveVarArgs = originalVarArgsType != null && originalVarArgsType.isPrimitive();
|
||||
this.varArgsConverter = isMethodVarArgs ? ValueConverter.fromAnnotatedType(methodParameters[methodParamCount - 1].getAnnotatedType()) : null;
|
||||
@SuppressWarnings("unchecked") final // Yes. Making a T is not worth
|
||||
@SuppressWarnings("unchecked") // Yes. Making a T is not worth
|
||||
OutputConverter<Object> converter = OutputConverter.get((Class<Object>) method.getReturnType());
|
||||
this.outputConverter = converter;
|
||||
|
||||
this.isEffectivelyVarArgs = isMethodVarArgs || Arrays.stream(valueConverters).anyMatch(ValueConverter::consumesVariableArgs);
|
||||
this.minParams = Arrays.stream(valueConverters).mapToInt(ValueConverter::valueConsumption).sum(); // Note: In !varargs, this is params
|
||||
int maxParams = this.minParams; // Unlimited == Integer.MAX_VALUE
|
||||
int setMaxParams = this.minParams; // Unlimited == Integer.MAX_VALUE
|
||||
if (this.isEffectivelyVarArgs)
|
||||
{
|
||||
maxParams = method.getAnnotation(ScarpetFunction.class).maxParams();
|
||||
if (maxParams == UNDEFINED_PARAMS)
|
||||
setMaxParams = method.getAnnotation(ScarpetFunction.class).maxParams();
|
||||
if (setMaxParams == UNDEFINED_PARAMS)
|
||||
{
|
||||
throw new IllegalArgumentException("No maximum number of params specified for " + name + ", use ScarpetFunction.UNLIMITED_PARAMS for unlimited. "
|
||||
+ "Provided in " + originClass);
|
||||
}
|
||||
if (maxParams == ScarpetFunction.UNLIMITED_PARAMS)
|
||||
if (setMaxParams == ScarpetFunction.UNLIMITED_PARAMS)
|
||||
{
|
||||
maxParams = Integer.MAX_VALUE;
|
||||
setMaxParams = Integer.MAX_VALUE;
|
||||
}
|
||||
if (maxParams < this.minParams)
|
||||
if (setMaxParams < this.minParams)
|
||||
{
|
||||
throw new IllegalArgumentException("Provided maximum number of params for " + name + " is smaller than method's param count."
|
||||
+ "Provided in " + originClass);
|
||||
}
|
||||
}
|
||||
this.maxParams = maxParams;
|
||||
this.maxParams = setMaxParams;
|
||||
|
||||
// Why MethodHandles?
|
||||
// MethodHandles are blazing fast (in some situations they can even compile to a single invokeVirtual), but slightly complex to work with.
|
||||
@@ -242,9 +242,9 @@ public final class AnnotationParser
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyValue apply(final Context context, final Context.Type t, final List<LazyValue> lazyValues)
|
||||
public LazyValue apply(Context context, Context.Type t, List<LazyValue> lazyValues)
|
||||
{
|
||||
final List<Value> lv = AbstractLazyFunction.unpackLazy(lazyValues, context, contextType);
|
||||
List<Value> lv = AbstractLazyFunction.unpackLazy(lazyValues, context, contextType);
|
||||
if (isEffectivelyVarArgs)
|
||||
{
|
||||
if (lv.size() < minParams)
|
||||
@@ -258,12 +258,12 @@ public final class AnnotationParser
|
||||
+ getUsage());
|
||||
}
|
||||
}
|
||||
final Object[] params = getMethodParams(lv, context, t);
|
||||
Object[] params = getMethodParams(lv, context, t);
|
||||
try
|
||||
{
|
||||
return outputConverter.convert(handle.invokeExact(params));
|
||||
}
|
||||
catch (final Throwable e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (e instanceof RuntimeException re)
|
||||
{
|
||||
@@ -274,12 +274,12 @@ public final class AnnotationParser
|
||||
}
|
||||
|
||||
// Hot code: Must be optimized
|
||||
private Object[] getMethodParams(final List<Value> lv, final Context context, final Context.Type theLazyT)
|
||||
private Object[] getMethodParams(List<Value> lv, Context context, Context.Type theLazyT)
|
||||
{
|
||||
final Object[] params = new Object[methodParamCount];
|
||||
final ListIterator<Value> lvIterator = lv.listIterator();
|
||||
Object[] params = new Object[methodParamCount];
|
||||
ListIterator<Value> lvIterator = lv.listIterator();
|
||||
|
||||
final int regularArgs = isMethodVarArgs ? methodParamCount - 1 : methodParamCount;
|
||||
int regularArgs = isMethodVarArgs ? methodParamCount - 1 : methodParamCount;
|
||||
for (int i = 0; i < regularArgs; i++)
|
||||
{
|
||||
params[i] = valueConverters[i].checkAndConvert(lvIterator, context, theLazyT);
|
||||
@@ -290,14 +290,14 @@ public final class AnnotationParser
|
||||
}
|
||||
if (isMethodVarArgs)
|
||||
{
|
||||
final int remaining = lv.size() - lvIterator.nextIndex();
|
||||
final Object[] varArgs;
|
||||
int remaining = lv.size() - lvIterator.nextIndex();
|
||||
Object[] varArgs;
|
||||
if (varArgsConverter.consumesVariableArgs())
|
||||
{
|
||||
final List<Object> varArgsList = new ArrayList<>(); // fastutil's is extremely slow in toArray, and we use that
|
||||
List<Object> varArgsList = new ArrayList<>(); // fastutil's is extremely slow in toArray, and we use that
|
||||
while (lvIterator.hasNext())
|
||||
{
|
||||
final Object obj = varArgsConverter.checkAndConvert(lvIterator, context, theLazyT);
|
||||
Object obj = varArgsConverter.checkAndConvert(lvIterator, context, theLazyT);
|
||||
if (obj == null)
|
||||
{
|
||||
throw new InternalExpressionException("Incorrect argument passsed to '" + name + "' function.\n" + getUsage());
|
||||
@@ -326,7 +326,7 @@ public final class AnnotationParser
|
||||
public String getUsage()
|
||||
{
|
||||
// Possibility: More descriptive messages using param.getName()? Would need changing gradle setup to keep those
|
||||
final StringBuilder builder = new StringBuilder("Usage: '");
|
||||
StringBuilder builder = new StringBuilder("Usage: '");
|
||||
builder.append(name);
|
||||
builder.append('(');
|
||||
builder.append(Arrays.stream(valueConverters).map(ValueConverter::getTypeName).filter(Objects::nonNull).collect(Collectors.joining(", ")));
|
||||
|
||||
@@ -10,6 +10,8 @@ import carpet.script.Context;
|
||||
import carpet.script.value.ListValue;
|
||||
import carpet.script.value.Value;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* <p>Converts a given {@link ListValue} into a {@link List} of values converted to {@code <T>}.</p>
|
||||
*
|
||||
@@ -32,18 +34,20 @@ final class ListConverter<T> implements ValueConverter<List<T>>
|
||||
return (allowSingletonCreation ? itemConverter.getTypeName() + " or " : "") + "list of " + itemConverter.getTypeName() + "s";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<T> convert(final Value value, final Context context)
|
||||
public List<T> convert(Value value, @Nullable Context context)
|
||||
{
|
||||
return value instanceof ListValue ? convertListValue((ListValue) value, context) : allowSingletonCreation ? convertSingleton(value, context) : null;
|
||||
}
|
||||
|
||||
private List<T> convertListValue(final ListValue values, final Context context)
|
||||
@Nullable
|
||||
private List<T> convertListValue(ListValue values, @Nullable Context context)
|
||||
{
|
||||
final List<T> list = new ArrayList<>(values.getItems().size());
|
||||
for (final Value value : values)
|
||||
List<T> list = new ArrayList<>(values.getItems().size());
|
||||
for (Value value : values)
|
||||
{
|
||||
final T converted = itemConverter.convert(value, context);
|
||||
T converted = itemConverter.convert(value, context);
|
||||
if (converted == null)
|
||||
{
|
||||
return null;
|
||||
@@ -53,9 +57,10 @@ final class ListConverter<T> implements ValueConverter<List<T>>
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<T> convertSingleton(final Value val, final Context context)
|
||||
@Nullable
|
||||
private List<T> convertSingleton(Value val, @Nullable Context context)
|
||||
{
|
||||
final T converted = itemConverter.convert(val, context);
|
||||
T converted = itemConverter.convert(val, context);
|
||||
if (converted == null)
|
||||
{
|
||||
return null;
|
||||
@@ -64,7 +69,7 @@ final class ListConverter<T> implements ValueConverter<List<T>>
|
||||
|
||||
}
|
||||
|
||||
private ListConverter(final AnnotatedType itemType, final boolean allowSingletonCreation)
|
||||
private ListConverter(AnnotatedType itemType, boolean allowSingletonCreation)
|
||||
{
|
||||
itemConverter = ValueConverter.fromAnnotatedType(itemType);
|
||||
this.allowSingletonCreation = allowSingletonCreation;
|
||||
@@ -84,11 +89,11 @@ final class ListConverter<T> implements ValueConverter<List<T>>
|
||||
* @param annotatedType The type to get generics information from
|
||||
* @return A new {@link ListConverter} for the data specified in the {@link AnnotatedType}
|
||||
*/
|
||||
static ListConverter<?> fromAnnotatedType(final AnnotatedType annotatedType)
|
||||
static ListConverter<?> fromAnnotatedType(AnnotatedType annotatedType)
|
||||
{
|
||||
final AnnotatedParameterizedType paramType = (AnnotatedParameterizedType) annotatedType;
|
||||
final AnnotatedType itemType = paramType.getAnnotatedActualTypeArguments()[0];
|
||||
final boolean allowSingletonCreation = annotatedType.isAnnotationPresent(Param.AllowSingleton.class);
|
||||
AnnotatedParameterizedType paramType = (AnnotatedParameterizedType) annotatedType;
|
||||
AnnotatedType itemType = paramType.getAnnotatedActualTypeArguments()[0];
|
||||
boolean allowSingletonCreation = annotatedType.isAnnotationPresent(Param.AllowSingleton.class);
|
||||
return new ListConverter<>(itemType, allowSingletonCreation);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ import carpet.script.value.BlockValue;
|
||||
import carpet.script.value.FunctionValue;
|
||||
import carpet.script.value.Value;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
@@ -122,7 +124,7 @@ public interface Locator
|
||||
super();
|
||||
}
|
||||
|
||||
static <R> ValueConverter<R> fromAnnotatedType(final AnnotatedType annoType, final Class<R> type)
|
||||
static <R> ValueConverter<R> fromAnnotatedType(AnnotatedType annoType, Class<R> type)
|
||||
{
|
||||
if (annoType.isAnnotationPresent(Block.class))
|
||||
{
|
||||
@@ -146,7 +148,7 @@ public interface Locator
|
||||
private final boolean anyString;
|
||||
private final boolean optional;
|
||||
|
||||
public BlockLocator(final Block annotation, final Class<R> type)
|
||||
public BlockLocator(Block annotation, Class<R> type)
|
||||
{
|
||||
super();
|
||||
this.acceptString = annotation.acceptString();
|
||||
@@ -163,8 +165,9 @@ public interface Locator
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <R> java.util.function.Function<BlockArgument, R> getReturnFunction(final Class<R> type)
|
||||
private static <R> java.util.function.Function<BlockArgument, R> getReturnFunction(Class<R> type)
|
||||
{
|
||||
if (type == BlockArgument.class)
|
||||
{
|
||||
@@ -192,9 +195,9 @@ public interface Locator
|
||||
}
|
||||
|
||||
@Override
|
||||
public R checkAndConvert(final Iterator<Value> valueIterator, final Context context, final Context.Type theLazyT)
|
||||
public R checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
||||
{
|
||||
final BlockArgument locator = BlockArgument.findIn((CarpetContext) context, valueIterator, 0, acceptString, optional, anyString);
|
||||
BlockArgument locator = BlockArgument.findIn((CarpetContext) context, valueIterator, 0, acceptString, optional, anyString);
|
||||
return returnFunction.apply(locator);
|
||||
}
|
||||
}
|
||||
@@ -205,7 +208,7 @@ public interface Locator
|
||||
private final boolean optionalEntity;
|
||||
private final boolean returnVec3d;
|
||||
|
||||
public Vec3dLocator(final Vec3d annotation, final Class<R> type)
|
||||
public Vec3dLocator(Vec3d annotation, Class<R> type)
|
||||
{
|
||||
this.optionalDirection = annotation.optionalDirection();
|
||||
this.optionalEntity = annotation.optionalEntity();
|
||||
@@ -227,10 +230,10 @@ public interface Locator
|
||||
}
|
||||
|
||||
@Override
|
||||
public R checkAndConvert(final Iterator<Value> valueIterator, final Context context, final Context.Type theLazyT)
|
||||
public R checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
||||
{
|
||||
final Vector3Argument locator = Vector3Argument.findIn(valueIterator, 0, optionalDirection, optionalEntity);
|
||||
@SuppressWarnings("unchecked") final R ret = (R) (returnVec3d ? locator.vec : locator);
|
||||
Vector3Argument locator = Vector3Argument.findIn(valueIterator, 0, optionalDirection, optionalEntity);
|
||||
@SuppressWarnings("unchecked") R ret = (R) (returnVec3d ? locator.vec : locator);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -241,7 +244,7 @@ public interface Locator
|
||||
private final boolean allowNone;
|
||||
private final boolean checkArgs;
|
||||
|
||||
FunctionLocator(final Function annotation, final Class<R> type)
|
||||
FunctionLocator(Function annotation, Class<R> type)
|
||||
{
|
||||
super();
|
||||
this.returnFunctionValue = type == FunctionValue.class;
|
||||
@@ -258,11 +261,11 @@ public interface Locator
|
||||
}
|
||||
|
||||
@Override
|
||||
public R checkAndConvert(final Iterator<Value> valueIterator, final Context context, final Context.Type theLazyT)
|
||||
public R checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
||||
{
|
||||
final Module module = context.host.main;
|
||||
final FunctionArgument locator = FunctionArgument.findIn(context, module, Lists.newArrayList(valueIterator), 0, allowNone, checkArgs);
|
||||
@SuppressWarnings("unchecked") final R ret = (R) (returnFunctionValue ? locator.function : locator);
|
||||
Module module = context.host.main;
|
||||
FunctionArgument locator = FunctionArgument.findIn(context, module, Lists.newArrayList(valueIterator), 0, allowNone, checkArgs);
|
||||
@SuppressWarnings("unchecked") R ret = (R) (returnFunctionValue ? locator.function : locator);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -276,7 +279,7 @@ public interface Locator
|
||||
private abstract static class AbstractLocator<R> implements ValueConverter<R>, Locator
|
||||
{
|
||||
@Override
|
||||
public R convert(final Value value, final Context context)
|
||||
public R convert(Value value, @Nullable Context context)
|
||||
{
|
||||
throw new UnsupportedOperationException("Cannot call a locator in a parameter that doesn't contain a context!");
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ import carpet.script.value.ListValue;
|
||||
import carpet.script.value.MapValue;
|
||||
import carpet.script.value.Value;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* <p>Converts a {@link MapValue} to a {@link Map}, converting all of its contents to their respective types.</p>
|
||||
*
|
||||
@@ -37,15 +39,15 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<K, V> convert(final Value value, final Context context)
|
||||
public Map<K, V> convert(Value value, @Nullable Context context)
|
||||
{
|
||||
final Map<K, V> result = new HashMap<>();
|
||||
Map<K, V> result = new HashMap<>();
|
||||
if (value instanceof MapValue)
|
||||
{
|
||||
for (final Entry<Value, Value> entry : ((MapValue) value).getMap().entrySet())
|
||||
for (Entry<Value, Value> entry : ((MapValue) value).getMap().entrySet())
|
||||
{
|
||||
final K key = keyConverter.convert(entry.getKey(), context);
|
||||
final V val = valueConverter.convert(entry.getValue(), context);
|
||||
K key = keyConverter.convert(entry.getKey(), context);
|
||||
V val = valueConverter.convert(entry.getValue(), context);
|
||||
if (key == null || val == null)
|
||||
{
|
||||
return null;
|
||||
@@ -57,7 +59,7 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
||||
return null;
|
||||
}
|
||||
|
||||
private MapConverter(final AnnotatedType keyType, final AnnotatedType valueType)
|
||||
private MapConverter(AnnotatedType keyType, AnnotatedType valueType)
|
||||
{
|
||||
super();
|
||||
keyConverter = ValueConverter.fromAnnotatedType(keyType);
|
||||
@@ -80,9 +82,9 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
||||
* @param annotatedType The type to get generics information from
|
||||
* @return A new {@link MapConverter} for the data specified in the {@link AnnotatedType}
|
||||
*/
|
||||
static MapConverter<?, ?> fromAnnotatedType(final AnnotatedType annotatedType)
|
||||
static MapConverter<?, ?> fromAnnotatedType(AnnotatedType annotatedType)
|
||||
{
|
||||
final AnnotatedType[] annotatedGenerics = ((AnnotatedParameterizedType) annotatedType).getAnnotatedActualTypeArguments();
|
||||
AnnotatedType[] annotatedGenerics = ((AnnotatedParameterizedType) annotatedType).getAnnotatedActualTypeArguments();
|
||||
return annotatedType.isAnnotationPresent(Param.KeyValuePairs.class)
|
||||
? new PairConverter<>(annotatedGenerics[0], annotatedGenerics[1], annotatedType.getAnnotation(Param.KeyValuePairs.class))
|
||||
: new MapConverter<>(annotatedGenerics[0], annotatedGenerics[1]);
|
||||
@@ -92,7 +94,7 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
||||
{
|
||||
private final boolean acceptMultiParam;
|
||||
|
||||
private PairConverter(final AnnotatedType keyType, final AnnotatedType valueType, final Param.KeyValuePairs config)
|
||||
private PairConverter(AnnotatedType keyType, AnnotatedType valueType, Param.KeyValuePairs config)
|
||||
{
|
||||
super(keyType, valueType);
|
||||
acceptMultiParam = config.allowMultiparam();
|
||||
@@ -104,26 +106,28 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
||||
return acceptMultiParam;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Map<K, V> convert(final Value value, final Context context) {
|
||||
public Map<K, V> convert(Value value, @Nullable 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, final Context context)
|
||||
@Nullable
|
||||
private Map<K, V> convertList(List<Value> valueList, @Nullable Context context)
|
||||
{
|
||||
if (valueList.size() % 2 == 1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
final Map<K, V> map = new HashMap<>();
|
||||
final Iterator<Value> val = valueList.iterator();
|
||||
Map<K, V> map = new HashMap<>();
|
||||
Iterator<Value> val = valueList.iterator();
|
||||
while (val.hasNext())
|
||||
{
|
||||
final K key = keyConverter.convert(val.next(), context);
|
||||
final V value = valueConverter.convert(val.next(), context);
|
||||
K key = keyConverter.convert(val.next(), context);
|
||||
V value = valueConverter.convert(val.next(), context);
|
||||
if (key == null || value == null)
|
||||
{
|
||||
return null;
|
||||
@@ -133,20 +137,21 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
||||
return map;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Map<K, V> checkAndConvert(final Iterator<Value> valueIterator, final Context context, final Context.Type theLazyT)
|
||||
public Map<K, V> checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
||||
{
|
||||
if (!valueIterator.hasNext())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
final Value val = valueIterator.next();
|
||||
Value val = valueIterator.next();
|
||||
if (!acceptMultiParam || val instanceof MapValue || (val instanceof ListValue && !(keyConverter instanceof ListConverter)))
|
||||
{
|
||||
return convert(val, context); // @KeyValuePairs Map<List<Something>, Boolean> will not support list consumption
|
||||
}
|
||||
|
||||
final Map<K, V> map = new HashMap<>();
|
||||
Map<K, V> map = new HashMap<>();
|
||||
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)
|
||||
|
||||
@@ -9,6 +9,8 @@ import java.util.Optional;
|
||||
import carpet.script.Context;
|
||||
import carpet.script.value.Value;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* <p>{@link ValueConverter} that accepts a parameter to not be present on function call.</p>
|
||||
*
|
||||
@@ -49,14 +51,15 @@ final class OptionalConverter<R> implements ValueConverter<Optional<R>>
|
||||
* @implNote Unlike most other converters, {@link OptionalConverter} will not call this method from
|
||||
* {@link #checkAndConvert(Iterator, Context, Context.Type)} and is only used as a fallback in types that don't support it.
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public Optional<R> convert(final Value value, final Context context)
|
||||
public Optional<R> convert(Value value, @Nullable Context context)
|
||||
{
|
||||
if (value.isNull())
|
||||
{
|
||||
return Optional.empty();
|
||||
}
|
||||
final R converted = typeConverter.convert(value, context);
|
||||
R converted = typeConverter.convert(value, context);
|
||||
if (converted == null)
|
||||
{
|
||||
return null;
|
||||
@@ -64,15 +67,16 @@ final class OptionalConverter<R> implements ValueConverter<Optional<R>>
|
||||
return Optional.of(converted);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Optional<R> checkAndConvert(final Iterator<Value> valueIterator, final Context context, final Context.Type theLazyT)
|
||||
public Optional<R> checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
||||
{
|
||||
if (!valueIterator.hasNext() || valueIterator.next().isNull())
|
||||
{
|
||||
return Optional.empty();
|
||||
}
|
||||
((ListIterator<Value>) valueIterator).previous();
|
||||
final R converted = typeConverter.checkAndConvert(valueIterator, context, theLazyT);
|
||||
R converted = typeConverter.checkAndConvert(valueIterator, context, theLazyT);
|
||||
if (converted == null)
|
||||
{
|
||||
return null;
|
||||
@@ -106,10 +110,10 @@ final class OptionalConverter<R> implements ValueConverter<Optional<R>>
|
||||
* @param annotatedType The type to get generics information from
|
||||
* @return A new {@link OptionalConverter} for the data specified in the {@link AnnotatedType}
|
||||
*/
|
||||
static OptionalConverter<?> fromAnnotatedType(final AnnotatedType annotatedType)
|
||||
static OptionalConverter<?> fromAnnotatedType(AnnotatedType annotatedType)
|
||||
{
|
||||
final AnnotatedParameterizedType paramType = (AnnotatedParameterizedType) annotatedType;
|
||||
final AnnotatedType wrappedType = paramType.getAnnotatedActualTypeArguments()[0];
|
||||
AnnotatedParameterizedType paramType = (AnnotatedParameterizedType) annotatedType;
|
||||
AnnotatedType wrappedType = paramType.getAnnotatedActualTypeArguments()[0];
|
||||
return new OptionalConverter<>(wrappedType);
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,8 @@ import carpet.script.value.StringValue;
|
||||
import carpet.script.value.Value;
|
||||
import carpet.script.value.ValueConversions;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* <p>A converter from a given {@link Object} of type T into a {@link LazyValue}, used in order to convert the outputs of methods into usable Scarpet
|
||||
* values.</p>
|
||||
@@ -57,7 +59,7 @@ public final class OutputConverter<T>
|
||||
|
||||
private final Function<T, LazyValue> converter;
|
||||
|
||||
private OutputConverter(final Function<T, LazyValue> converter)
|
||||
private OutputConverter(Function<T, LazyValue> converter)
|
||||
{
|
||||
this.converter = converter;
|
||||
}
|
||||
@@ -90,7 +92,7 @@ public final class OutputConverter<T>
|
||||
* @param input The value to convert
|
||||
* @return The converted value
|
||||
*/
|
||||
public LazyValue convert(final T input)
|
||||
public LazyValue convert(@Nullable T input)
|
||||
{
|
||||
return input == null ? LazyValue.NULL : converter.apply(input);
|
||||
}
|
||||
@@ -103,9 +105,9 @@ public final class OutputConverter<T>
|
||||
* @param inputType The class of T
|
||||
* @param converter The function that converts the an instance of T to a {@link LazyValue}
|
||||
*/
|
||||
public static <T> void register(final Class<T> inputType, final Function<T, LazyValue> converter)
|
||||
public static <T> void register(Class<T> inputType, Function<T, LazyValue> converter)
|
||||
{
|
||||
final OutputConverter<T> instance = new OutputConverter<>(converter);
|
||||
OutputConverter<T> instance = new OutputConverter<>(converter);
|
||||
if (byResult.containsKey(inputType))
|
||||
{
|
||||
throw new IllegalArgumentException(inputType + " already has a registered OutputConverter");
|
||||
@@ -122,9 +124,9 @@ public final class OutputConverter<T>
|
||||
* @param inputType The class of T
|
||||
* @param converter The function that converts an instance of T to a {@link Value}
|
||||
*/
|
||||
public static <T> void registerToValue(final Class<T> inputType, final Function<T, Value> converter)
|
||||
public static <T> void registerToValue(Class<T> inputType, Function<T, Value> converter)
|
||||
{
|
||||
final OutputConverter<T> instance = new OutputConverter<>(converter.andThen(v -> (c, t) -> v));
|
||||
OutputConverter<T> instance = new OutputConverter<>(converter.andThen(v -> (c, t) -> v));
|
||||
if (byResult.containsKey(inputType))
|
||||
{
|
||||
throw new IllegalArgumentException(inputType + " already has a registered OutputConverter");
|
||||
|
||||
@@ -24,6 +24,8 @@ import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
@@ -143,18 +145,23 @@ public interface Param
|
||||
* <p>A {@link ValueConverter} that outputs the {@link Context} in which the function has been called, and throws {@link UnsupportedOperationException} when trying to convert a {@link Value}
|
||||
* directly.</p>
|
||||
*/
|
||||
static final ValueConverter<Context> CONTEXT_PROVIDER = new ValueConverter<Context>()
|
||||
static final ValueConverter<Context> CONTEXT_PROVIDER = new ValueConverter<>()
|
||||
{
|
||||
@Override public String getTypeName() { return null; }
|
||||
@Nullable
|
||||
@Override
|
||||
public String getTypeName()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context convert(final Value value, final Context context)
|
||||
public Context convert(Value value, @Nullable Context context)
|
||||
{
|
||||
throw new UnsupportedOperationException("Called convert() with Value in Context Provider converter, where only checkAndConvert is supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context checkAndConvert(final Iterator<Value> valueIterator, final Context context, final Context.Type theLazyT)
|
||||
public Context checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
@@ -170,18 +177,23 @@ public interface Param
|
||||
* <p>A {@link ValueConverter} that outputs the {@link Context.Type} which the function has been called, or throws {@link UnsupportedOperationException} when trying to convert a {@link Value}
|
||||
* directly.</p>
|
||||
*/
|
||||
static final ValueConverter<Context.Type> CONTEXT_TYPE_PROVIDER = new ValueConverter<Context.Type>()
|
||||
static final ValueConverter<Context.Type> CONTEXT_TYPE_PROVIDER = new ValueConverter<>()
|
||||
{
|
||||
@Override public String getTypeName() { return null; }
|
||||
@Nullable
|
||||
@Override
|
||||
public String getTypeName()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context.Type convert(final Value value, final Context context)
|
||||
public Context.Type convert(Value value, @Nullable Context context)
|
||||
{
|
||||
throw new UnsupportedOperationException("Called convert() with a Value in TheLazyT Provider, where only checkAndConvert is supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context.Type checkAndConvert(final Iterator<Value> valueIterator, final Context context, final Context.Type theLazyT)
|
||||
public Context.Type checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
||||
{
|
||||
return theLazyT;
|
||||
}
|
||||
@@ -214,12 +226,12 @@ public interface Param
|
||||
* @throws IllegalArgumentException If the type doesn't accept the {@link Strict} annotation or if it has been used incorrectly (shallow in
|
||||
* unsupported places)
|
||||
*/
|
||||
static ValueConverter<?> getStrictConverter(final AnnotatedType type)
|
||||
static ValueConverter<?> getStrictConverter(AnnotatedType type)
|
||||
{
|
||||
final boolean shallow = type.getAnnotation(Strict.class).shallow();
|
||||
final Class<?> clazz = (Class<?>) type.getType();
|
||||
final StrictConverterInfo key = new StrictConverterInfo(clazz, shallow);
|
||||
final ValueConverter<?> converter = strictParamsByClassAndShallowness.get(key);
|
||||
boolean shallow = type.getAnnotation(Strict.class).shallow();
|
||||
Class<?> clazz = (Class<?>) type.getType();
|
||||
StrictConverterInfo key = new StrictConverterInfo(clazz, shallow);
|
||||
ValueConverter<?> converter = strictParamsByClassAndShallowness.get(key);
|
||||
if (converter != null)
|
||||
{
|
||||
return converter;
|
||||
@@ -239,9 +251,9 @@ public interface Param
|
||||
* @param shallow {@code true} if you are registering a shallow-strict parameter, {@code false} if a "fully" strict one
|
||||
* @param converter The {@link ValueConverter} for the given type and shallowness.
|
||||
*/
|
||||
public static <T> void registerStrictConverter(final Class<T> type, final boolean shallow, final ValueConverter<T> converter)
|
||||
public static <T> void registerStrictConverter(Class<T> type, boolean shallow, ValueConverter<T> converter)
|
||||
{
|
||||
final StrictConverterInfo key = new StrictConverterInfo(type, shallow);
|
||||
StrictConverterInfo key = new StrictConverterInfo(type, shallow);
|
||||
if (strictParamsByClassAndShallowness.containsKey(key))
|
||||
{
|
||||
throw new IllegalArgumentException(type + " already has a registered " + (shallow ? "" : "non-") + "shallow StrictConverter");
|
||||
@@ -271,16 +283,16 @@ public interface Param
|
||||
* avoid possible collisions with other extensions.
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // this makes no sense... But I guess its preferable to enforce typesafety in callers
|
||||
public static <T> void registerCustomConverterFactory(final BiFunction<AnnotatedType, Class<T>, ValueConverter<T>> factory)
|
||||
public static <T> void registerCustomConverterFactory(BiFunction<AnnotatedType, Class<T>, ValueConverter<T>> factory)
|
||||
{
|
||||
customFactories.add((BiFunction<AnnotatedType, Class<?>, ValueConverter<?>>) (Object) factory);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // Stored correctly
|
||||
static <R> ValueConverter<R> getCustomConverter(final AnnotatedType annoType, final Class<R> type)
|
||||
static <R> ValueConverter<R> getCustomConverter(AnnotatedType annoType, Class<R> type)
|
||||
{
|
||||
ValueConverter<R> result;
|
||||
for (final BiFunction<AnnotatedType, Class<?>, ValueConverter<?>> factory : customFactories)
|
||||
for (BiFunction<AnnotatedType, Class<?>, ValueConverter<?>> factory : customFactories)
|
||||
{
|
||||
if ((result = (ValueConverter<R>) factory.apply(annoType, type)) != null)
|
||||
{
|
||||
|
||||
@@ -18,6 +18,8 @@ import carpet.script.value.NumericValue;
|
||||
import carpet.script.value.Value;
|
||||
import carpet.script.value.ValueConversions;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* <p>A simple {@link ValueConverter} implementation that converts from a specified subclass of {@link Value} into {@code <R>} by using a given
|
||||
* function.</p>
|
||||
@@ -61,7 +63,7 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
|
||||
*
|
||||
* @see #SimpleTypeConverter(Class, BiFunction, String)
|
||||
*/
|
||||
public SimpleTypeConverter(final Class<T> inputType, final Function<T, R> converter, final String typeName)
|
||||
public SimpleTypeConverter(Class<T> inputType, Function<T, R> converter, String typeName)
|
||||
{
|
||||
this(inputType, (v, c) -> converter.apply(v), typeName);
|
||||
}
|
||||
@@ -77,7 +79,7 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
|
||||
* @param converter The function to convert an instance of inputType into R, with the context of the call.
|
||||
* @param typeName The name of the type for error messages
|
||||
*/
|
||||
public SimpleTypeConverter(final Class<T> inputType, final BiFunction<T, Context, R> converter, final String typeName)
|
||||
public SimpleTypeConverter(Class<T> inputType, BiFunction<T, Context, R> converter, String typeName)
|
||||
{
|
||||
super();
|
||||
this.converter = converter;
|
||||
@@ -99,14 +101,15 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
|
||||
* @return The {@link SimpleTypeConverter} for the specified outputType
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // T always extends Value, R is always the same as map's key, since map is private.
|
||||
static <R> SimpleTypeConverter<Value, R> get(final Class<R> outputType)
|
||||
static <R> SimpleTypeConverter<Value, R> get(Class<R> outputType)
|
||||
{
|
||||
return (SimpleTypeConverter<Value, R>) byResult.get(outputType);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@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, final Context context) // and adds millions of casts. This one is even removed
|
||||
public R convert(Value value, @Nullable Context context) // and adds millions of casts. This one is even removed
|
||||
{
|
||||
return valueClass.isInstance(value) ? converter.apply((T)value, context) : null;
|
||||
}
|
||||
@@ -125,8 +128,8 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
|
||||
*
|
||||
* @see #registerType(Class, Class, BiFunction, String)
|
||||
*/
|
||||
public static <T extends Value, R> void registerType(final Class<T> requiredInputType, final Class<R> outputType,
|
||||
final Function<T, R> converter, final String typeName)
|
||||
public static <T extends Value, R> void registerType(Class<T> requiredInputType, Class<R> outputType,
|
||||
Function<T, R> converter, String typeName)
|
||||
{
|
||||
registerType(requiredInputType, outputType, (val, ctx) -> converter.apply(val), typeName);
|
||||
}
|
||||
@@ -143,10 +146,10 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
|
||||
* 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 BiFunction<T, Context, R> converter, final String typeName)
|
||||
public static <T extends Value, R> void registerType(Class<T> requiredInputType, Class<R> outputType,
|
||||
BiFunction<T, Context, R> converter, String typeName)
|
||||
{
|
||||
final SimpleTypeConverter<T, R> type = new SimpleTypeConverter<>(requiredInputType, converter, typeName);
|
||||
SimpleTypeConverter<T, R> type = new SimpleTypeConverter<>(requiredInputType, converter, typeName);
|
||||
byResult.put(outputType, type);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,8 @@ import carpet.script.value.StringValue;
|
||||
import carpet.script.value.ThreadValue;
|
||||
import carpet.script.value.Value;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* <p>Simple {@link ValueConverter} implementation that casts a {@link Value} into one of its subclasses, either for use directly in parameters or
|
||||
* converters, or as an already working middle step.</p>
|
||||
@@ -51,7 +53,7 @@ public final class ValueCaster<R> implements ValueConverter<R> // R always exten
|
||||
private final Class<R> outputType;
|
||||
private final String typeName;
|
||||
|
||||
private ValueCaster(final Class<R> outputType, final String typeName)
|
||||
private ValueCaster(Class<R> outputType, String typeName)
|
||||
{
|
||||
super();
|
||||
this.outputType = outputType;
|
||||
@@ -73,14 +75,15 @@ public final class ValueCaster<R> implements ValueConverter<R> // R always exten
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // Casters are stored with their exact class, for sure since the map is private (&& class has same generic as
|
||||
// caster)
|
||||
public static <R> ValueCaster<R> get(final Class<R> outputType)
|
||||
public static <R> ValueCaster<R> get(Class<R> outputType)
|
||||
{
|
||||
return (ValueCaster<R>) byResult.get(outputType);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@SuppressWarnings("unchecked") // more than checked, see SimpleTypeConverter#converter for reasoning
|
||||
public R convert(final Value value, final Context context)
|
||||
public R convert(Value value, @Nullable Context context)
|
||||
{
|
||||
if (!outputType.isInstance(value))
|
||||
{
|
||||
@@ -98,9 +101,9 @@ public final class ValueCaster<R> implements ValueConverter<R> // R always exten
|
||||
* required<!--, with the form //Outdated concept <code>(function name) requires a (typeName) to be passed as (argName, if
|
||||
* available)</code>-->
|
||||
*/
|
||||
public static <R extends Value> void register(final Class<R> valueClass, final String typeName)
|
||||
public static <R extends Value> void register(Class<R> valueClass, String typeName)
|
||||
{
|
||||
final ValueCaster<R> caster = new ValueCaster<>(valueClass, typeName);
|
||||
ValueCaster<R> caster = new ValueCaster<>(valueClass, typeName);
|
||||
byResult.putIfAbsent(valueClass, caster);
|
||||
}
|
||||
}
|
||||
@@ -9,12 +9,13 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.commons.lang3.ClassUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import carpet.script.Context;
|
||||
import carpet.script.annotation.Param.Params;
|
||||
import carpet.script.value.Value;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* <p>Classes implementing this interface are able to convert {@link Value} instances into {@code <R>}, in order to easily use them in parameters for
|
||||
* Scarpet functions created using the {@link ScarpetFunction} annotation.</p>
|
||||
@@ -37,6 +38,7 @@ public interface ValueConverter<R>
|
||||
* @apiNote This method is intended to only be called when an error has occurred and therefore there is a need to print a stacktrace with some
|
||||
* helpful usage instructions.
|
||||
*/
|
||||
@Nullable
|
||||
String getTypeName();
|
||||
|
||||
/**
|
||||
@@ -63,7 +65,7 @@ public interface ValueConverter<R>
|
||||
* <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, final Context context);
|
||||
@Nullable R convert(Value value, @Nullable Context context);
|
||||
|
||||
/**
|
||||
* Old version of {@link #convert(Value)} without taking a {@link Context}.<p>
|
||||
@@ -75,8 +77,9 @@ public interface ValueConverter<R>
|
||||
* @return A converted value
|
||||
* @deprecated Calling this method instead of {@link #convert(Value, Context)} may not return values for some converters
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated(forRemoval = true)
|
||||
default R convert(final Value value)
|
||||
default R convert(Value value)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -130,7 +133,7 @@ public interface ValueConverter<R>
|
||||
* @return A usable {@link ValueConverter} to convert from a {@link Value} to {@code <R>}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
static <R> ValueConverter<R> fromAnnotatedType(final AnnotatedType annoType)
|
||||
static <R> ValueConverter<R> fromAnnotatedType(AnnotatedType annoType)
|
||||
{
|
||||
Class<R> type = annoType.getType() instanceof ParameterizedType ? // We are defining R here.
|
||||
(Class<R>) ((ParameterizedType) annoType.getType()).getRawType() :
|
||||
@@ -208,7 +211,8 @@ public interface ValueConverter<R>
|
||||
* @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)
|
||||
@Nullable
|
||||
default R checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type contextType)
|
||||
{
|
||||
return !valueIterator.hasNext() ? null : convert(valueIterator.next(), context);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user