Files
fabric-carpet/src/main/java/carpet/script/annotation/ValueCaster.java
T
altrisi cc7a9c01be Annotated Scarpet (#772)
* Progress by now.

* Output conversions plus a few extra random things

* More progress, mostly list converting and a way to get converters

* Apply ValueConverters, refactor valueconverter getter to

accept types with annotations and generics, made listconverter pass
those params and annotations recursively. And probably more things.

* Some extra docs, the 100% most important thing

* Added MapConverter, strict Strings and Texts, some docs additions

and commented out heuristics

* Rework StrictParam to use SimpleTypeConverters and be saved in a map

* Minor changes and docs & added non-fully-functional context "converter"

* Added support for variable value count converters, multi-value eaters &

0 value eaters (Context).

* Docs update, enable Context converter, fix minor TODOs

* Move (most) parameter annotations into a single class,

remove deprecated ValueCaster#cast, update some docs.

* Small refactor of Param.Strict registering, added boolean to it

* Added PairConverter, moved Context and LV ValueConverters to Params

* Document public methods of AnnotationParser

* Add a lot more docs, make it ready for the first preview PR

* Move ValueConverter population outside of makeFunction,

check lv size for > max arguments, minor doc updates and workaround for
Mercury#28 until released

* Added optional parameters (declared using Java's Optional),

made evalAndConvert check for the presence of the next iteration,
updated test class

* Generalize Value OutputConverter

* ListConverter and MapConverter now follow ValueConverter contract of

incorrect value handling, returning a complete null for an incorrect
value anywhere. Also small fix to OptionalConverter and docs.
Getting ready for checking null in AnnotationParser!

* Change reflection's #invoke to a MethodHandle to boost speed by a lot

Commented

* Dedupe code, update and remove outdated todos, add 2 new ValueCasters

* Merge lambdas in display_title2 test function to be more accurate

* Check nulls somehow, I guess

* Move base function logic into a class to stop

passing hundreds of parameters into static functions and therefore simplify it

* Reduce visibility and fix a bug with PairConverter

* Hide Context provider in usage report

* Add support for primitive varargs

* Added TheLazyT converter

* Drop #getPrefixedTypeName and use 'something' as name of values

* Use value again because of varargs, document that

* Remove a completed TODO

* Remove old disabled heuristic value type name getter

* Fix TheLazyT

* Preparing locators before touching current Carpet infrastructure

* Add notes about non-implementedness of remaining locators

* Added APIs to register custom ValueConverters

* Mention new APIs in javadocs

* Adapt to new Carpet changes and deprecated non-implemented annotations

* Update example function for display_title()

* Better implementation for player_list example

* Fix example error message

* FunctionArgument no longer has generics

* Modernize Text converters

* OutputConverter is final, plus other small changes

* Few non-behavioural changes

* Rename LazyFunction to ScarpetFunction

* Drop LazyValue in parameters, not in return

Updating docs was a nightmare

* CARPET CHANGE - Make Fluff.AbstractLazyFunction.unpackArgs call unpackLazy (was duped)

* Make errors more like current Scarpet errors

* Allow customizing ContextType when evaluating arguments

* Add a few missing docs, comment out outdated ValueCaster doc

It's been a while, wow

* Fix for new Carpet signature :irritatered:

Please don't break API methods! Extensions may be using them, and they
will just crash the game or behave in unexpected ways else!

* Format all code to Carpet's. Powered by Eclipse

Reviewed to be sure it's ok. No functional changes, except from a small correction

* Always use full name for Context.Type

* Add parsing for all current Scarpet api and language classes

And remove test functions

* Allow void return type

* Fix no param methods

Whoops!

* Remove outdated comment and fix small javadoc linting problem

* Drop Param.TheLazyT in favour of just Context.Type type

And small performance improvement to varargs varargs since fastutil's toArray is crap

* Quote functions in error messages

* Make SimpleTypeConverter independent of ValueCaster

'Real world' usage demonstrated it can be annoying else, mostly for wrapper only values where you just want the wrapped object
2021-05-21 01:33:00 -03:00

102 lines
3.9 KiB
Java

package carpet.script.annotation;
import java.util.HashMap;
import java.util.Map;
import carpet.script.value.AbstractListValue;
import carpet.script.value.BlockValue;
import carpet.script.value.BooleanValue;
import carpet.script.value.EntityValue;
import carpet.script.value.FormattedTextValue;
import carpet.script.value.FunctionValue;
import carpet.script.value.ListValue;
import carpet.script.value.MapValue;
import carpet.script.value.NBTSerializableValue;
import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
import carpet.script.value.ThreadValue;
import carpet.script.value.Value;
/**
* <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>
*
* <p>{@link ValueCaster}s are reused whenever asked for one, since they don't have any complexity.</p>
*
* @see #register(Class, String)
*
* @param <R> The {@link Value} subclass this {@link ValueCaster} casts to
*/
public final class ValueCaster<R> implements ValueConverter<R> // R always extends Value, not explicitly because of type checking
{
private static final Map<Class<? extends Value>, ValueCaster<? extends Value>> byResult = new HashMap<>();
static
{
register(Value.class, "value");
register(BlockValue.class, "block");
register(EntityValue.class, "entity");
register(FormattedTextValue.class, "formatted text");
register(FunctionValue.class, "function");
register(ListValue.class, "list");
register(MapValue.class, "map");
register(AbstractListValue.class, "list or similar"); // For LazyListValue basically? Not sure what should use this
register(NBTSerializableValue.class, "nbt object");
register(NumericValue.class, "number");
register(BooleanValue.class, "boolean");
register(StringValue.class, "string");
register(ThreadValue.class, "thread");
}
private final Class<R> outputType;
private final String typeName;
private ValueCaster(Class<R> outputType, String typeName)
{
this.outputType = outputType;
this.typeName = typeName;
}
@Override
public String getTypeName()
{
return typeName;
}
/**
* <p>Returns the registered {@link ValueCaster} for the specified outputType.</p>
*
* @param <R> The type of the {@link ValueCaster} you are looking for
* @param outputType The class of the {@link Value} the returned {@link ValueCaster} casts to
* @return The {@link ValueCaster} for the specified outputType
*/
@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(Class<R> outputType)
{
return (ValueCaster<R>) byResult.get(outputType);
}
@Override
public R convert(Value value)
{
if (!outputType.isInstance(value))
return null;
return outputType.cast(value);
}
/**
* <p>Registers a new {@link Value} to be able to use it in {@link SimpleTypeConverter}</p>
*
* @param <R> The {@link Value} subclass
* @param valueClass The class of T
* @param typeName A {@link String} representing the name of this type. It will be used in error messages when there is no higher type
* 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(Class<R> valueClass, String typeName)
{
ValueCaster<R> caster = new ValueCaster<R>(valueClass, typeName);
byResult.putIfAbsent(valueClass, caster);
}
}