diff --git a/build.gradle b/build.gradle index dc9180e7..f826d16c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ plugins { id "architectury-plugin" version "3.4-SNAPSHOT" - id "dev.architectury.loom" version "0.10.0-SNAPSHOT" apply false + id "dev.architectury.loom" version "0.11.0-SNAPSHOT" apply false + id "io.github.juuxel.loom-quiltflower" version "1.7.0" apply false } architectury { @@ -9,6 +10,7 @@ architectury { subprojects { apply plugin: "dev.architectury.loom" + apply plugin: "io.github.juuxel.loom-quiltflower" loom { silentMojangMappingsLicense() diff --git a/common/build.gradle b/common/build.gradle index 784fc1c0..9df4a61d 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -12,6 +12,10 @@ configurations { dev } +loom { + accessWidenerPath = file("src/main/resources/rhino.accesswidener") +} + artifacts { dev(jar) } diff --git a/common/src/main/java/dev/latvian/mods/rhino/Context.java b/common/src/main/java/dev/latvian/mods/rhino/Context.java index 2e7beeb1..c45bc178 100644 --- a/common/src/main/java/dev/latvian/mods/rhino/Context.java +++ b/common/src/main/java/dev/latvian/mods/rhino/Context.java @@ -11,8 +11,12 @@ import dev.latvian.mods.rhino.ast.AstRoot; import dev.latvian.mods.rhino.ast.ScriptNode; import dev.latvian.mods.rhino.classfile.ClassFileWriter.ClassFileFormatException; +import dev.latvian.mods.rhino.util.CustomJavaToJsWrapper; +import dev.latvian.mods.rhino.util.CustomJavaToJsWrapperProvider; +import dev.latvian.mods.rhino.util.CustomJavaToJsWrapperProviderHolder; import dev.latvian.mods.rhino.util.Remapper; import dev.latvian.mods.rhino.util.wrap.TypeWrappers; +import org.jetbrains.annotations.Nullable; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; @@ -25,6 +29,7 @@ import java.util.HashMap; import java.util.Locale; import java.util.Map; +import java.util.function.Predicate; /** * This class represents the runtime context of an executing script. @@ -1370,8 +1375,12 @@ public static Object javaToJS(Object value, Scriptable scope) { * @throws EvaluatorException if the conversion cannot be performed */ public static Object jsToJava(Object value, Class desiredType) throws EvaluatorException { + if (desiredType == null) { + return value; + } + Context cx = getCurrentContext(); - return NativeJavaObject.coerceTypeImpl(cx.hasTypeWrappers() ? cx.getTypeWrappers() : null, desiredType, value); + return NativeJavaObject.coerceTypeImpl(cx, cx.hasTypeWrappers() ? cx.getTypeWrappers() : null, desiredType, value); } /** @@ -1910,6 +1919,42 @@ public Remapper getRemapper() { return factory.remapper; } + @Nullable + @SuppressWarnings("unchecked") + public CustomJavaToJsWrapper wrapCustomJavaToJs(Object javaObject) { + if (factory.customScriptableWrappers.isEmpty()) { + return null; + } + + var provider = factory.customScriptableWrapperCache.get(javaObject.getClass()); + + if (provider == null) { + for (CustomJavaToJsWrapperProviderHolder wrapper : factory.customScriptableWrappers) { + provider = wrapper.create(javaObject); + + if (provider != null) { + break; + } + } + + if (provider == null) { + provider = CustomJavaToJsWrapperProvider.NONE; + } + + factory.customScriptableWrapperCache.put(javaObject.getClass(), provider); + } + + return provider.create(javaObject); + } + + public void addCustomJavaToJsWrapper(Predicate predicate, CustomJavaToJsWrapperProvider provider) { + factory.customScriptableWrappers.add(new CustomJavaToJsWrapperProviderHolder<>(predicate, provider)); + } + + public void addCustomJavaToJsWrapper(Class type, CustomJavaToJsWrapperProvider provider) { + addCustomJavaToJsWrapper(new CustomJavaToJsWrapperProviderHolder.PredicateFromClass<>(type), provider); + } + private final ContextFactory factory; private boolean sealed; private Object sealKey; diff --git a/common/src/main/java/dev/latvian/mods/rhino/ContextFactory.java b/common/src/main/java/dev/latvian/mods/rhino/ContextFactory.java index d2bd032b..3e94fe1c 100644 --- a/common/src/main/java/dev/latvian/mods/rhino/ContextFactory.java +++ b/common/src/main/java/dev/latvian/mods/rhino/ContextFactory.java @@ -8,10 +8,17 @@ package dev.latvian.mods.rhino; +import dev.latvian.mods.rhino.util.CustomJavaToJsWrapperProvider; +import dev.latvian.mods.rhino.util.CustomJavaToJsWrapperProviderHolder; import dev.latvian.mods.rhino.util.DefaultRemapper; import dev.latvian.mods.rhino.util.Remapper; import dev.latvian.mods.rhino.util.wrap.TypeWrappers; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** * Factory class that Rhino runtime uses to create new {@link Context} * instances. A ContextFactory can also notify listeners @@ -114,6 +121,8 @@ public class ContextFactory { private boolean disabledListening; TypeWrappers typeWrappers; Remapper remapper = DefaultRemapper.INSTANCE; + final List> customScriptableWrappers = new ArrayList<>(); + final Map, CustomJavaToJsWrapperProvider> customScriptableWrapperCache = new HashMap<>(); /** * Listener of {@link Context} creation and release events. diff --git a/common/src/main/java/dev/latvian/mods/rhino/NativeJavaList.java b/common/src/main/java/dev/latvian/mods/rhino/NativeJavaList.java index bf116776..1d094e35 100644 --- a/common/src/main/java/dev/latvian/mods/rhino/NativeJavaList.java +++ b/common/src/main/java/dev/latvian/mods/rhino/NativeJavaList.java @@ -6,6 +6,8 @@ package dev.latvian.mods.rhino; import dev.latvian.mods.rhino.util.Deletable; +import dev.latvian.mods.rhino.util.ValueUnwrapper; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Arrays; @@ -18,10 +20,18 @@ @SuppressWarnings({"rawtypes", "unchecked"}) public class NativeJavaList extends NativeJavaObject { private final List list; + private final Class listType; + private final ValueUnwrapper valueUnwrapper; - public NativeJavaList(Scriptable scope, Object jo, List list) { + public NativeJavaList(Scriptable scope, Object jo, List list, @Nullable Class listType, ValueUnwrapper valueUnwrapper) { super(scope, jo, jo.getClass()); this.list = list; + this.listType = listType; + this.valueUnwrapper = valueUnwrapper; + } + + public NativeJavaList(Scriptable scope, Object jo, List list) { + this(scope, jo, list, null, ValueUnwrapper.DEFAULT); } @Override @@ -48,9 +58,7 @@ public boolean has(Symbol key, Scriptable start) { @Override public Object get(int index, Scriptable start) { if (isWithValidIndex(index)) { - Context cx = Context.getContext(); - Object obj = list.get(index); - return cx.getWrapFactory().wrap(cx, this, obj, obj.getClass()); + return valueUnwrapper.unwrap(this, list.get(index)); } return Undefined.instance; } @@ -66,7 +74,7 @@ public Object get(Symbol key, Scriptable start) { @Override public void put(int index, Scriptable start, Object value) { if (isWithValidIndex(index)) { - list.set(index, Context.jsToJava(value, Object.class)); + list.set(index, Context.jsToJava(value, listType)); return; } super.put(index, start, value); @@ -121,9 +129,15 @@ private int getLength() { private int push(Object[] args) { if (args.length == 1) { - list.add(args[0]); + list.add(Context.jsToJava(args[0], listType)); } else if (args.length > 1) { - list.addAll(Arrays.asList(args)); + Object[] args1 = new Object[args.length]; + + for (int i = 0; i < args.length; i++) { + args1[i] = Context.jsToJava(args[i], listType); + } + + list.addAll(Arrays.asList(args1)); } return list.size(); @@ -147,7 +161,7 @@ private Object shift() { private int unshift(Object[] args) { for (int i = args.length - 1; i >= 0; i--) { - list.add(0, args[i]); + list.add(0, Context.jsToJava(args[i], listType)); } return list.size(); @@ -265,10 +279,10 @@ private Object reduce(Object[] args) { } BinaryOperator operator = (BinaryOperator) args[0]; - Object o = list.get(0); + Object o = valueUnwrapper.unwrap(this, list.get(0)); for (int i = 1; i < list.size(); i++) { - o = operator.apply(o, list.get(i)); + o = valueUnwrapper.unwrap(this, operator.apply(o, valueUnwrapper.unwrap(this, list.get(i)))); } return o; @@ -282,10 +296,10 @@ private Object reduceRight(Object[] args) { } BinaryOperator operator = (BinaryOperator) args[0]; - Object o = list.get(0); + Object o = valueUnwrapper.unwrap(this, list.get(0)); for (int i = list.size() - 1; i >= 1; i--) { - o = operator.apply(o, list.get(i)); + o = valueUnwrapper.unwrap(this, operator.apply(o, valueUnwrapper.unwrap(this, list.get(i)))); } return o; diff --git a/common/src/main/java/dev/latvian/mods/rhino/NativeJavaMap.java b/common/src/main/java/dev/latvian/mods/rhino/NativeJavaMap.java index b00345fb..2edd2837 100644 --- a/common/src/main/java/dev/latvian/mods/rhino/NativeJavaMap.java +++ b/common/src/main/java/dev/latvian/mods/rhino/NativeJavaMap.java @@ -6,6 +6,7 @@ package dev.latvian.mods.rhino; import dev.latvian.mods.rhino.util.Deletable; +import dev.latvian.mods.rhino.util.ValueUnwrapper; import java.util.ArrayList; import java.util.List; @@ -14,10 +15,18 @@ @SuppressWarnings({"rawtypes", "unchecked"}) public class NativeJavaMap extends NativeJavaObject { private final Map map; + private final Class mapValueType; + private final ValueUnwrapper valueUnwrapper; - public NativeJavaMap(Scriptable scope, Object jo, Map map) { + public NativeJavaMap(Scriptable scope, Object jo, Map map, Class mapValueType, ValueUnwrapper valueUnwrapper) { super(scope, jo, jo.getClass()); this.map = map; + this.mapValueType = mapValueType; + this.valueUnwrapper = valueUnwrapper; + } + + public NativeJavaMap(Scriptable scope, Object jo, Map map) { + this(scope, jo, map, Object.class, ValueUnwrapper.DEFAULT); } @Override @@ -25,7 +34,6 @@ public String getClassName() { return "JavaMap"; } - @Override public boolean has(String name, Scriptable start) { if (map.containsKey(name)) { @@ -45,9 +53,7 @@ public boolean has(int index, Scriptable start) { @Override public Object get(String name, Scriptable start) { if (map.containsKey(name)) { - Context cx = Context.getContext(); - Object obj = map.get(name); - return cx.getWrapFactory().wrap(cx, this, obj, obj.getClass()); + return valueUnwrapper.unwrap(this, map.get(name)); } return super.get(name, start); } @@ -55,21 +61,19 @@ public Object get(String name, Scriptable start) { @Override public Object get(int index, Scriptable start) { if (map.containsKey(index)) { - Context cx = Context.getContext(); - Object obj = map.get(index); - return cx.getWrapFactory().wrap(cx, this, obj, obj.getClass()); + return valueUnwrapper.unwrap(this, map.get(index)); } return super.get(index, start); } @Override public void put(String name, Scriptable start, Object value) { - map.put(name, Context.jsToJava(value, Object.class)); + map.put(name, Context.jsToJava(value, mapValueType)); } @Override public void put(int index, Scriptable start, Object value) { - map.put(index, Context.jsToJava(value, Object.class)); + map.put(index, Context.jsToJava(value, mapValueType)); } @Override diff --git a/common/src/main/java/dev/latvian/mods/rhino/NativeJavaObject.java b/common/src/main/java/dev/latvian/mods/rhino/NativeJavaObject.java index 2f8f2b32..36bba212 100644 --- a/common/src/main/java/dev/latvian/mods/rhino/NativeJavaObject.java +++ b/common/src/main/java/dev/latvian/mods/rhino/NativeJavaObject.java @@ -538,7 +538,7 @@ private static int getJSTypeCode(Object value) { * Type-munging for field setting and method invocation. * Conforms to LC3 specification */ - static Object coerceTypeImpl(@Nullable TypeWrappers typeWrappers, Class type, Object value) { + static Object coerceTypeImpl(Context cx, @Nullable TypeWrappers typeWrappers, Class type, Object value) { if (value == null || value.getClass() == type) { return value; } @@ -578,8 +578,7 @@ static Object coerceTypeImpl(@Nullable TypeWrappers typeWrappers, Class type, if (type == ScriptRuntime.StringClass) { return ScriptRuntime.toString(value); } else if (type == ScriptRuntime.ObjectClass) { - Context context = Context.getCurrentContext(); - if ((context != null) && context.hasFeature(Context.FEATURE_INTEGER_WITHOUT_DECIMAL_PLACE)) { + if (cx.hasFeature(Context.FEATURE_INTEGER_WITHOUT_DECIMAL_PLACE)) { //to process numbers like 2.0 as 2 without decimal place long roundedValue = Math.round(toDouble(value)); if (roundedValue == toDouble(value)) { @@ -657,7 +656,7 @@ static Object coerceTypeImpl(@Nullable TypeWrappers typeWrappers, Class type, Object Result = Array.newInstance(arrayType, (int) length); for (int i = 0; i < length; ++i) { try { - Array.set(Result, i, coerceTypeImpl(typeWrappers, arrayType, array.get(i, array))); + Array.set(Result, i, coerceTypeImpl(cx, typeWrappers, arrayType, array.get(i, array))); } catch (EvaluatorException ee) { return reportConversionError(value, type); } @@ -677,6 +676,7 @@ static Object coerceTypeImpl(@Nullable TypeWrappers typeWrappers, Class type, } } + return value; } diff --git a/common/src/main/java/dev/latvian/mods/rhino/Parser.java b/common/src/main/java/dev/latvian/mods/rhino/Parser.java index c7564d28..ef774bd1 100644 --- a/common/src/main/java/dev/latvian/mods/rhino/Parser.java +++ b/common/src/main/java/dev/latvian/mods/rhino/Parser.java @@ -2585,7 +2585,7 @@ private AstNode memberExprTail(boolean allowCallSyntax, AstNode pn) throws IOExc for (; ; ) { int tt = peekToken(); switch (tt) { - case Token.DOT: + case Token.DOT, Token.HOOK: lineno = ts.lineno; pn = propertyAccess(tt, pn); pn.setLineno(lineno); @@ -2667,6 +2667,12 @@ private AstNode propertyAccess(int tt, AstNode pn) throws IOException { codeBug(); } + boolean optionalChaining = tt == Token.HOOK && matchToken(Token.DOT, false); + + if (tt == Token.HOOK && !optionalChaining) { + reportError("msg.no.dot.after.hook"); + } + int lineno = ts.lineno, dotPos = ts.tokenBeg; consumeToken(); diff --git a/common/src/main/java/dev/latvian/mods/rhino/WrapFactory.java b/common/src/main/java/dev/latvian/mods/rhino/WrapFactory.java index 30950010..93ac2e49 100644 --- a/common/src/main/java/dev/latvian/mods/rhino/WrapFactory.java +++ b/common/src/main/java/dev/latvian/mods/rhino/WrapFactory.java @@ -8,7 +8,7 @@ package dev.latvian.mods.rhino; -import dev.latvian.mods.rhino.util.CustomJavaObjectWrapper; +import dev.latvian.mods.rhino.util.CustomJavaToJsWrapper; import dev.latvian.mods.rhino.util.JavaSetWrapper; import java.util.List; @@ -115,9 +115,17 @@ public Scriptable wrapNewObject(Context cx, Scriptable scope, Object obj) { * @return the wrapped value which shall not be null */ public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Object javaObject, Class staticType) { - if (javaObject instanceof CustomJavaObjectWrapper w) { - return w.wrapAsJavaObject(cx, scope, staticType); - } else if (javaObject instanceof Map map) { + if (javaObject instanceof CustomJavaToJsWrapper w) { + return w.convertJavaToJs(cx, scope, staticType); + } + + CustomJavaToJsWrapper w = cx.wrapCustomJavaToJs(javaObject); + + if (w != null) { + return w.convertJavaToJs(cx, scope, staticType); + } + + if (javaObject instanceof Map map) { return new NativeJavaMap(scope, map, map); } else if (javaObject instanceof List list) { return new NativeJavaList(scope, list, list); diff --git a/common/src/main/java/dev/latvian/mods/rhino/mod/core/mixin/common/CollectionTagMixin.java b/common/src/main/java/dev/latvian/mods/rhino/mod/core/mixin/common/CollectionTagMixin.java deleted file mode 100644 index e460415f..00000000 --- a/common/src/main/java/dev/latvian/mods/rhino/mod/core/mixin/common/CollectionTagMixin.java +++ /dev/null @@ -1,17 +0,0 @@ -package dev.latvian.mods.rhino.mod.core.mixin.common; - -import dev.latvian.mods.rhino.util.CollectionTagWrapper; -import dev.latvian.mods.rhino.util.CustomJavaObjectWrapper; -import net.minecraft.nbt.CollectionTag; -import net.minecraft.nbt.Tag; -import org.spongepowered.asm.mixin.Mixin; - -import java.util.List; - -@Mixin(CollectionTag.class) -public abstract class CollectionTagMixin implements CustomJavaObjectWrapper.AsList { - @Override - public List wrapAsJavaList() { - return new CollectionTagWrapper((CollectionTag) (Object) this); - } -} diff --git a/common/src/main/java/dev/latvian/mods/rhino/mod/core/mixin/common/CompoundTagMixin.java b/common/src/main/java/dev/latvian/mods/rhino/mod/core/mixin/common/CompoundTagMixin.java index d8f28251..ea41f59c 100644 --- a/common/src/main/java/dev/latvian/mods/rhino/mod/core/mixin/common/CompoundTagMixin.java +++ b/common/src/main/java/dev/latvian/mods/rhino/mod/core/mixin/common/CompoundTagMixin.java @@ -1,27 +1,12 @@ package dev.latvian.mods.rhino.mod.core.mixin.common; -import dev.latvian.mods.rhino.util.CompoundTagWrapper; -import dev.latvian.mods.rhino.util.CustomJavaObjectWrapper; import dev.latvian.mods.rhino.util.RemapForJS; import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.Tag; -import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import java.util.Map; - @Mixin(value = CompoundTag.class, priority = 1001) -public abstract class CompoundTagMixin implements CustomJavaObjectWrapper.AsMap { - @Shadow - @Final - private Map tags; - - @Override - public Map wrapAsJavaMap() { - return new CompoundTagWrapper((CompoundTag) (Object) this, tags); - } - +public abstract class CompoundTagMixin { @Shadow @RemapForJS("merge") public abstract CompoundTag merge(CompoundTag tag); diff --git a/common/src/main/java/dev/latvian/mods/rhino/mod/util/CollectionTagWrapper.java b/common/src/main/java/dev/latvian/mods/rhino/mod/util/CollectionTagWrapper.java new file mode 100644 index 00000000..4207377b --- /dev/null +++ b/common/src/main/java/dev/latvian/mods/rhino/mod/util/CollectionTagWrapper.java @@ -0,0 +1,15 @@ +package dev.latvian.mods.rhino.mod.util; + +import dev.latvian.mods.rhino.Context; +import dev.latvian.mods.rhino.NativeJavaList; +import dev.latvian.mods.rhino.Scriptable; +import dev.latvian.mods.rhino.util.CustomJavaToJsWrapper; +import net.minecraft.nbt.CollectionTag; +import net.minecraft.nbt.Tag; + +public record CollectionTagWrapper(CollectionTag tag) implements CustomJavaToJsWrapper { + @Override + public Scriptable convertJavaToJs(Context cx, Scriptable scope, Class staticType) { + return new NativeJavaList(scope, tag, tag, Tag.class, NBTUtils.VALUE_UNWRAPPER); + } +} diff --git a/common/src/main/java/dev/latvian/mods/rhino/mod/util/CompoundTagWrapper.java b/common/src/main/java/dev/latvian/mods/rhino/mod/util/CompoundTagWrapper.java new file mode 100644 index 00000000..69e08299 --- /dev/null +++ b/common/src/main/java/dev/latvian/mods/rhino/mod/util/CompoundTagWrapper.java @@ -0,0 +1,15 @@ +package dev.latvian.mods.rhino.mod.util; + +import dev.latvian.mods.rhino.Context; +import dev.latvian.mods.rhino.NativeJavaMap; +import dev.latvian.mods.rhino.Scriptable; +import dev.latvian.mods.rhino.util.CustomJavaToJsWrapper; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; + +public record CompoundTagWrapper(CompoundTag tag) implements CustomJavaToJsWrapper { + @Override + public Scriptable convertJavaToJs(Context cx, Scriptable scope, Class staticType) { + return new NativeJavaMap(scope, tag, tag.tags, Tag.class, NBTUtils.VALUE_UNWRAPPER); + } +} diff --git a/common/src/main/java/dev/latvian/mods/rhino/mod/util/NBTUtils.java b/common/src/main/java/dev/latvian/mods/rhino/mod/util/NBTUtils.java index cd644cc6..d007deb7 100644 --- a/common/src/main/java/dev/latvian/mods/rhino/mod/util/NBTUtils.java +++ b/common/src/main/java/dev/latvian/mods/rhino/mod/util/NBTUtils.java @@ -1,5 +1,6 @@ package dev.latvian.mods.rhino.mod.util; +import dev.latvian.mods.rhino.util.ValueUnwrapper; import io.netty.buffer.ByteBufInputStream; import io.netty.handler.codec.EncoderException; import net.minecraft.nbt.ByteArrayTag; @@ -7,6 +8,7 @@ import net.minecraft.nbt.CollectionTag; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.DoubleTag; +import net.minecraft.nbt.EndTag; import net.minecraft.nbt.FloatTag; import net.minecraft.nbt.IntArrayTag; import net.minecraft.nbt.IntTag; @@ -29,23 +31,38 @@ import java.io.IOException; import java.util.Collection; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; -/** - * @author LatvianModder - */ -public class NBTUtils { +public interface NBTUtils { + ValueUnwrapper VALUE_UNWRAPPER = (scope, value) -> value instanceof Tag tag ? fromTag(tag) : value; + @Nullable - public static Tag toNBT(@Nullable Object o) { - if (o instanceof Tag) { - return (Tag) o; - } else if (o instanceof NBTSerializable s) { + static Object fromTag(@Nullable Tag t) { + if (t == null || t == EndTag.INSTANCE) { + return null; + } else if (t instanceof StringTag) { + return t.getAsString(); + } else if (t instanceof NumericTag) { + return ((NumericTag) t).getAsNumber(); + } + + return t; + } + + @Nullable + static Tag toTag(@Nullable Object v) { + if (v == null || v instanceof EndTag) { + return null; + } else if (v instanceof Tag) { + return (Tag) v; + } else if (v instanceof NBTSerializable s) { return s.toNBT(); - } else if (o instanceof CharSequence || o instanceof Character) { - return StringTag.valueOf(o.toString()); - } else if (o instanceof Boolean b) { + } else if (v instanceof CharSequence || v instanceof Character) { + return StringTag.valueOf(v.toString()); + } else if (v instanceof Boolean b) { return ByteTag.valueOf(b ? (byte) 1 : (byte) 0); - } else if (o instanceof Number number) { + } else if (v instanceof Number number) { if (number instanceof Byte) { return ByteTag.valueOf(number.byteValue()); } else if (number instanceof Short) { @@ -59,11 +76,11 @@ public static Tag toNBT(@Nullable Object o) { } return DoubleTag.valueOf(number.doubleValue()); - } else if (o instanceof Map map) { + } else if (v instanceof Map map) { CompoundTag tag = new OrderedCompoundTag(); for (Map.Entry entry : map.entrySet()) { - Tag nbt1 = NBTUtils.toNBT(entry.getValue()); + Tag nbt1 = toTag(entry.getValue()); if (nbt1 != null) { tag.put(String.valueOf(entry.getKey()), nbt1); @@ -71,14 +88,19 @@ public static Tag toNBT(@Nullable Object o) { } return tag; - } else if (o instanceof Collection c) { - return toNBT(c); + } else if (v instanceof Collection c) { + return toTagCollection(c); } return null; } - public static CollectionTag toNBT(Collection c) { + @Nullable + static CompoundTag toTagCompound(@Nullable Object o) { + return (CompoundTag) toTag(o); + } + + static CollectionTag toTagCollection(Collection c) { if (c.isEmpty()) { return new ListTag(); } @@ -88,7 +110,7 @@ public static CollectionTag toNBT(Collection c) { byte commmonId = -1; for (Object o : c) { - values[s] = toNBT(o); + values[s] = toTag(o); if (values[s] != null) { if (commmonId == -1) { @@ -142,7 +164,115 @@ public static CollectionTag toNBT(Collection c) { return nbt; } - public static void quoteAndEscapeForJS(StringBuilder stringBuilder, String string) { + static Tag compoundTag() { + return new OrderedCompoundTag(); + } + + static Tag compoundTag(Map map) { + OrderedCompoundTag tag = new OrderedCompoundTag(); + + for (var entry : map.entrySet()) { + var tag1 = toTag(entry.getValue()); + + if (tag1 != null) { + tag.put(String.valueOf(entry.getKey()), tag1); + } + } + + return tag; + } + + static Tag listTag() { + return new ListTag(); + } + + static Tag listTag(List list) { + ListTag tag = new ListTag(); + + for (Object v : list) { + tag.add(toTag(v)); + } + + return tag; + } + + static Tag byteTag(byte v) { + return ByteTag.valueOf(v); + } + + static Tag b(byte v) { + return ByteTag.valueOf(v); + } + + static Tag shortTag(short v) { + return ShortTag.valueOf(v); + } + + static Tag s(short v) { + return ShortTag.valueOf(v); + } + + static Tag intTag(int v) { + return IntTag.valueOf(v); + } + + static Tag i(int v) { + return IntTag.valueOf(v); + } + + static Tag longTag(long v) { + return LongTag.valueOf(v); + } + + static Tag l(long v) { + return LongTag.valueOf(v); + } + + static Tag floatTag(float v) { + return FloatTag.valueOf(v); + } + + static Tag f(float v) { + return FloatTag.valueOf(v); + } + + static Tag doubleTag(double v) { + return DoubleTag.valueOf(v); + } + + static Tag d(double v) { + return DoubleTag.valueOf(v); + } + + static Tag stringTag(String v) { + return StringTag.valueOf(v); + } + + static Tag intArrayTag(int[] v) { + return new IntArrayTag(v); + } + + static Tag ia(int[] v) { + return new IntArrayTag(v); + } + + static Tag longArrayTag(long[] v) { + return new LongArrayTag(v); + } + + static Tag la(long[] v) { + return new LongArrayTag(v); + } + + static Tag byteArrayTag(byte[] v) { + return new ByteArrayTag(v); + } + + static Tag ba(byte[] v) { + return new ByteArrayTag(v); + } + + static void quoteAndEscapeForJS(StringBuilder stringBuilder, String string) { int start = stringBuilder.length(); stringBuilder.append(' '); char c = 0; @@ -172,11 +302,11 @@ public static void quoteAndEscapeForJS(StringBuilder stringBuilder, String strin stringBuilder.append(c); } - private static TagType convertType(TagType tagType) { + static TagType convertType(TagType tagType) { return tagType == CompoundTag.TYPE ? COMPOUND_TYPE : tagType == ListTag.TYPE ? LIST_TYPE : tagType; } - private static final TagType COMPOUND_TYPE = new TagType.VariableSize() { + TagType COMPOUND_TYPE = new TagType.VariableSize<>() { @Override public OrderedCompoundTag load(DataInput dataInput, int i, NbtAccounter nbtAccounter) throws IOException { nbtAccounter.accountBits(384L); @@ -272,7 +402,7 @@ public String getPrettyName() { } }; - private static final TagType LIST_TYPE = new TagType.VariableSize() { + TagType LIST_TYPE = new TagType.VariableSize<>() { @Override public ListTag load(DataInput dataInput, int i, NbtAccounter nbtAccounter) throws IOException { nbtAccounter.accountBits(296L); @@ -359,7 +489,7 @@ public String getPrettyName() { }; @Nullable - public static OrderedCompoundTag read(FriendlyByteBuf buf) { + static OrderedCompoundTag read(FriendlyByteBuf buf) { int i = buf.readerIndex(); byte b = buf.readByte(); if (b == 0) { diff --git a/common/src/main/java/dev/latvian/mods/rhino/mod/util/NBTWrapper.java b/common/src/main/java/dev/latvian/mods/rhino/mod/util/NBTWrapper.java deleted file mode 100644 index d7b5a457..00000000 --- a/common/src/main/java/dev/latvian/mods/rhino/mod/util/NBTWrapper.java +++ /dev/null @@ -1,160 +0,0 @@ -package dev.latvian.mods.rhino.mod.util; - -import net.minecraft.nbt.ByteArrayTag; -import net.minecraft.nbt.ByteTag; -import net.minecraft.nbt.DoubleTag; -import net.minecraft.nbt.EndTag; -import net.minecraft.nbt.FloatTag; -import net.minecraft.nbt.IntArrayTag; -import net.minecraft.nbt.IntTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.LongArrayTag; -import net.minecraft.nbt.LongTag; -import net.minecraft.nbt.NumericTag; -import net.minecraft.nbt.ShortTag; -import net.minecraft.nbt.StringTag; -import net.minecraft.nbt.Tag; -import org.jetbrains.annotations.Nullable; - -import java.util.List; -import java.util.Map; - -public interface NBTWrapper { - @Nullable - static Object fromTag(@Nullable Tag t) { - if (t == null || t == EndTag.INSTANCE) { - return null; - } else if (t instanceof StringTag) { - return t.getAsString(); - } else if (t instanceof NumericTag) { - return ((NumericTag) t).getAsNumber(); - } - - return t; - } - - @Nullable - static Tag toTag(@Nullable Object v) { - if (v == null || v == EndTag.INSTANCE) { - return null; - } else if (v instanceof Tag) { - return (Tag) v; - } else if (v instanceof String) { - return StringTag.valueOf(v.toString()); - } else if (v instanceof Number) { - return DoubleTag.valueOf(((Number) v).doubleValue()); - } else if (v instanceof Boolean) { - return ByteTag.valueOf((Boolean) v); - } else if (v instanceof Map) { - return compoundTag((Map) v); - } else if (v instanceof List) { - return listTag((List) v); - } - - return null; - } - - static Tag compoundTag() { - return new OrderedCompoundTag(); - } - - static Tag compoundTag(Map map) { - OrderedCompoundTag tag = new OrderedCompoundTag(); - - for (Map.Entry e : map.entrySet()) { - tag.put(e.getKey(), toTag(e.getValue())); - } - - return tag; - } - - static Tag listTag() { - return new ListTag(); - } - - static Tag listTag(List list) { - ListTag tag = new ListTag(); - - for (Object v : list) { - tag.add(toTag(v)); - } - - return tag; - } - - static Tag byteTag(byte v) { - return ByteTag.valueOf(v); - } - - static Tag b(byte v) { - return ByteTag.valueOf(v); - } - - static Tag shortTag(short v) { - return ShortTag.valueOf(v); - } - - static Tag s(short v) { - return ShortTag.valueOf(v); - } - - static Tag intTag(int v) { - return IntTag.valueOf(v); - } - - static Tag i(int v) { - return IntTag.valueOf(v); - } - - static Tag longTag(long v) { - return LongTag.valueOf(v); - } - - static Tag l(long v) { - return LongTag.valueOf(v); - } - - static Tag floatTag(float v) { - return FloatTag.valueOf(v); - } - - static Tag f(float v) { - return FloatTag.valueOf(v); - } - - static Tag doubleTag(double v) { - return DoubleTag.valueOf(v); - } - - static Tag d(double v) { - return DoubleTag.valueOf(v); - } - - static Tag stringTag(String v) { - return StringTag.valueOf(v); - } - - static Tag intArrayTag(int[] v) { - return new IntArrayTag(v); - } - - static Tag ia(int[] v) { - return new IntArrayTag(v); - } - - static Tag longArrayTag(long[] v) { - return new LongArrayTag(v); - } - - static Tag la(long[] v) { - return new LongArrayTag(v); - } - - static Tag byteArrayTag(byte[] v) { - return new ByteArrayTag(v); - } - - static Tag ba(byte[] v) { - return new ByteArrayTag(v); - } -} diff --git a/common/src/main/java/dev/latvian/mods/rhino/util/CollectionTagWrapper.java b/common/src/main/java/dev/latvian/mods/rhino/util/CollectionTagWrapper.java deleted file mode 100644 index 0bb6652e..00000000 --- a/common/src/main/java/dev/latvian/mods/rhino/util/CollectionTagWrapper.java +++ /dev/null @@ -1,63 +0,0 @@ -package dev.latvian.mods.rhino.util; - -import dev.latvian.mods.rhino.Wrapper; -import dev.latvian.mods.rhino.mod.util.NBTWrapper; -import net.minecraft.nbt.CollectionTag; -import net.minecraft.nbt.Tag; -import org.jetbrains.annotations.Nullable; - -import java.util.AbstractList; - -public class CollectionTagWrapper extends AbstractList implements Wrapper { - private final CollectionTag tags; - - public CollectionTagWrapper(CollectionTag tags) { - this.tags = tags; - } - - @Override - public Object unwrap() { - return tags; - } - - @Nullable - @Override - public Object get(int index) { - return NBTWrapper.fromTag(tags.get(index)); - } - - @Override - public int size() { - return tags.size(); - } - - @Override - public boolean add(Object value) { - return tags.add(NBTWrapper.toTag(value)); - } - - @Override - public void add(int index, Object value) { - tags.add(index, NBTWrapper.toTag(value)); - } - - @Override - public Object set(int index, Object value) { - return NBTWrapper.fromTag(tags.set(index, NBTWrapper.toTag(value))); - } - - @Override - public Object remove(int index) { - return NBTWrapper.fromTag(tags.remove(index)); - } - - @Override - public boolean remove(Object value) { - return tags.remove(NBTWrapper.toTag(value)); - } - - @Override - public void clear() { - tags.clear(); - } -} diff --git a/common/src/main/java/dev/latvian/mods/rhino/util/CompoundTagWrapper.java b/common/src/main/java/dev/latvian/mods/rhino/util/CompoundTagWrapper.java deleted file mode 100644 index 17298946..00000000 --- a/common/src/main/java/dev/latvian/mods/rhino/util/CompoundTagWrapper.java +++ /dev/null @@ -1,73 +0,0 @@ -package dev.latvian.mods.rhino.util; - -import dev.latvian.mods.rhino.Wrapper; -import dev.latvian.mods.rhino.mod.util.NBTWrapper; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.Tag; - -import java.util.AbstractMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -public class CompoundTagWrapper extends AbstractMap implements Wrapper { - private final CompoundTag compoundTag; - private final Map tags; - - public CompoundTagWrapper(CompoundTag compoundTag, Map tags) { - this.compoundTag = compoundTag; - this.tags = tags; - } - - @Override - public Object unwrap() { - return compoundTag; - } - - @Override - public Object get(Object key) { - return NBTWrapper.fromTag(tags.get(key)); - } - - @Override - public boolean containsKey(Object key) { - return tags.containsKey(key); - } - - @Override - public Object put(String key, Object v) { - Tag t = NBTWrapper.toTag(v); - - if (t == null) { - return NBTWrapper.fromTag(tags.remove(key)); - } else { - return NBTWrapper.fromTag(tags.put(key, t)); - } - } - - @Override - public Set keySet() { - return tags.keySet(); - } - - @Override - public Set> entrySet() { - Set> set = new LinkedHashSet<>(); - - for (Map.Entry entry : tags.entrySet()) { - set.add(new AbstractMap.SimpleEntry<>(entry.getKey(), NBTWrapper.fromTag(entry.getValue()))); - } - - return set; - } - - @Override - public Object remove(Object key) { - return NBTWrapper.fromTag(tags.remove(key)); - } - - @Override - public void clear() { - tags.clear(); - } -} diff --git a/common/src/main/java/dev/latvian/mods/rhino/util/CustomJavaObjectWrapper.java b/common/src/main/java/dev/latvian/mods/rhino/util/CustomJavaObjectWrapper.java deleted file mode 100644 index 0723e395..00000000 --- a/common/src/main/java/dev/latvian/mods/rhino/util/CustomJavaObjectWrapper.java +++ /dev/null @@ -1,39 +0,0 @@ -package dev.latvian.mods.rhino.util; - -import dev.latvian.mods.rhino.Context; -import dev.latvian.mods.rhino.NativeJavaList; -import dev.latvian.mods.rhino.NativeJavaMap; -import dev.latvian.mods.rhino.Scriptable; -import dev.latvian.mods.rhino.Wrapper; - -import java.util.List; -import java.util.Map; - -@FunctionalInterface -public interface CustomJavaObjectWrapper { - Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Class staticType); - - @FunctionalInterface - interface AsList extends CustomJavaObjectWrapper { - List wrapAsJavaList(); - - @Override - default Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Class staticType) { - List list = wrapAsJavaList(); - Object jo = Wrapper.unwrapped(list); - return new NativeJavaList(scope, jo, list); - } - } - - @FunctionalInterface - interface AsMap extends CustomJavaObjectWrapper { - Map wrapAsJavaMap(); - - @Override - default Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Class staticType) { - Map map = wrapAsJavaMap(); - Object jo = Wrapper.unwrapped(map); - return new NativeJavaMap(scope, jo, map); - } - } -} diff --git a/common/src/main/java/dev/latvian/mods/rhino/util/CustomJavaToJsWrapper.java b/common/src/main/java/dev/latvian/mods/rhino/util/CustomJavaToJsWrapper.java new file mode 100644 index 00000000..6d368168 --- /dev/null +++ b/common/src/main/java/dev/latvian/mods/rhino/util/CustomJavaToJsWrapper.java @@ -0,0 +1,9 @@ +package dev.latvian.mods.rhino.util; + +import dev.latvian.mods.rhino.Context; +import dev.latvian.mods.rhino.Scriptable; + +@FunctionalInterface +public interface CustomJavaToJsWrapper { + Scriptable convertJavaToJs(Context cx, Scriptable scope, Class staticType); +} diff --git a/common/src/main/java/dev/latvian/mods/rhino/util/CustomJavaToJsWrapperProvider.java b/common/src/main/java/dev/latvian/mods/rhino/util/CustomJavaToJsWrapperProvider.java new file mode 100644 index 00000000..58b6428a --- /dev/null +++ b/common/src/main/java/dev/latvian/mods/rhino/util/CustomJavaToJsWrapperProvider.java @@ -0,0 +1,11 @@ +package dev.latvian.mods.rhino.util; + +import org.jetbrains.annotations.Nullable; + +@FunctionalInterface +public interface CustomJavaToJsWrapperProvider { + CustomJavaToJsWrapperProvider NONE = object -> null; + + @Nullable + CustomJavaToJsWrapper create(T object); +} diff --git a/common/src/main/java/dev/latvian/mods/rhino/util/CustomJavaToJsWrapperProviderHolder.java b/common/src/main/java/dev/latvian/mods/rhino/util/CustomJavaToJsWrapperProviderHolder.java new file mode 100644 index 00000000..c57982d9 --- /dev/null +++ b/common/src/main/java/dev/latvian/mods/rhino/util/CustomJavaToJsWrapperProviderHolder.java @@ -0,0 +1,23 @@ +package dev.latvian.mods.rhino.util; + +import org.jetbrains.annotations.Nullable; + +import java.util.function.Predicate; + +public record CustomJavaToJsWrapperProviderHolder(Predicate predicate, CustomJavaToJsWrapperProvider provider) { + @Nullable + public CustomJavaToJsWrapperProvider create(T object) { + if (predicate.test(object)) { + return provider; + } + + return null; + } + + public record PredicateFromClass(Class type) implements Predicate { + @Override + public boolean test(T object) { + return type.isAssignableFrom(object.getClass()); + } + } +} diff --git a/common/src/main/java/dev/latvian/mods/rhino/util/ValueUnwrapper.java b/common/src/main/java/dev/latvian/mods/rhino/util/ValueUnwrapper.java new file mode 100644 index 00000000..d1518754 --- /dev/null +++ b/common/src/main/java/dev/latvian/mods/rhino/util/ValueUnwrapper.java @@ -0,0 +1,14 @@ +package dev.latvian.mods.rhino.util; + +import dev.latvian.mods.rhino.Context; +import dev.latvian.mods.rhino.Scriptable; + +@FunctionalInterface +public interface ValueUnwrapper { + ValueUnwrapper DEFAULT = (scope, value) -> { + Context cx = Context.getContext(); + return cx.getWrapFactory().wrap(cx, scope, value, value.getClass()); + }; + + Object unwrap(Scriptable scope, Object value); +} diff --git a/common/src/main/java/dev/latvian/mods/rhino/util/wrap/TypeWrappers.java b/common/src/main/java/dev/latvian/mods/rhino/util/wrap/TypeWrappers.java index 801d00db..2dafafd8 100644 --- a/common/src/main/java/dev/latvian/mods/rhino/util/wrap/TypeWrappers.java +++ b/common/src/main/java/dev/latvian/mods/rhino/util/wrap/TypeWrappers.java @@ -15,10 +15,6 @@ public class TypeWrappers { private final Map, TypeWrapper> wrappers = new LinkedHashMap<>(); - public void removeAll() { - wrappers.clear(); - } - @Deprecated public void register(String id, Class from, Class to, Function factory) { // Keep old one for now so that it doesn't crash diff --git a/common/src/main/resources/dev/latvian/mods/rhino/resources/Messages.properties b/common/src/main/resources/dev/latvian/mods/rhino/resources/Messages.properties index a32a4ee7..5ecf6632 100644 --- a/common/src/main/resources/dev/latvian/mods/rhino/resources/Messages.properties +++ b/common/src/main/resources/dev/latvian/mods/rhino/resources/Messages.properties @@ -229,6 +229,8 @@ msg.missing.semi=\ missing ; after statement msg.no.name.after.dot=\ missing name after . operator +msg.no.dot.after.hook=\ + missing . after ? operator msg.no.name.after.coloncolon=\ missing name after :: operator msg.no.name.after.dotdot=\ diff --git a/common/src/main/resources/dev/latvian/mods/rhino/resources/Messages_fr.properties b/common/src/main/resources/dev/latvian/mods/rhino/resources/Messages_fr.properties deleted file mode 100644 index b32d3a1b..00000000 --- a/common/src/main/resources/dev/latvian/mods/rhino/resources/Messages_fr.properties +++ /dev/null @@ -1,562 +0,0 @@ -# -# French JavaScript messages file. -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# Codegen -msg.dup.parms=\ - Le nom de param\u00E8tre "{0}" existe d\u00E9j\u00E0. -msg.too.big.jump=\ - Programme trop complexe: d\u00E9calage de saut trop important -msg.too.big.index=\ - Programme trop complexe: l''indice interne d\u00E9passe la limite de 64\u00a0ko -msg.while.compiling.fn=\ - Une erreur de g\u00e9n\u00e9ration de code a \u00e9t\u00e9 rencontr\u00e9e \u00e0 la compilation de la fonction "{0}": {1} -msg.while.compiling.script=\ - Une erreur de g\u00e9n\u00e9ration de code a \u00e9t\u00e9 rencontr\u00e9e \u00e0 la compilation du script: {0} -# Context -msg.ctor.not.found=\ - Le constructeur de "{0}" est introuvable -msg.not.ctor=\ - {0} n''est pas un constructeur -# FunctionObject -msg.varargs.ctor=\ - La m\u00E9thode ou le constructeur "{0}" doit \u00EAtre statique avec la signature \ - "(Context cx, Object[] args, Function ctorObj, boolean inNewExpr)" \ - pour d\u00E9finir un constructeur d''arguments de variable. -msg.varargs.fun=\ - La m\u00E9thode "{0}" doit \u00EAtre statique avec la signature \ - "(Context cx, Scriptable thisObj, Object[] args, Function funObj)" \ - pour d\u00E9finir une fonction d''arguments de variable -msg.incompat.call=\ - La m\u00E9thode "{0}" a \u00E9t\u00E9 appel\u00E9e dans un objet non compatible -msg.bad.parms=\ - Les param\u00E8tres de la m\u00E9thode sont incorrects pour "{0}" -msg.bad.method.return=\ - Le type de retour "{0}" de la m\u00e9thode "{1}" est incorrect. -msg.bad.ctor.return=\ - La construction d''objets du type "{0}" n''est pas possible. -msg.no.overload=\ - La m\u00E9thode "{0}" appara\u00EEt plusieurs fois dans la classe "{1}" -msg.method.not.found=\ - La m\u00E9thode "{0}" est introuvable dans "{1}" -# IRFactory -msg.bad.for.in.lhs=\ - La partie gauche de la boucle for..in est incorrecte -msg.mult.index=\ - Une seule variable est autoris\u00E9e dans la boucle for..in -msg.bad.for.in.destruct=\ - La partie gauche de la boucle for..in doit \u00eatre un tableau de longueur 2 pour accepter \ - une paire clef/valeur. -msg.cant.convert=\ - La conversion en type "{0}" est impossible -msg.bad.assign.left=\ - La partie gauche de l''affectation est incorrecte -msg.bad.decr=\ - L''op\u00e9rande d\u00e9cr\u00e9ment\u00e9e est incorrecte. -msg.bad.incr=\ - L''op\u00e9rande incr\u00e9ment\u00e9e est incorrecte. -msg.bad.yield=\ - ''yield'' doit \u00eatre dans une fonction. -msg.yield.parenthesized=\ - L''expression suivant ''yield'' doit \u00eatre entre parenth\u00e8ses. -# NativeGlobal -msg.cant.call.indirect=\ - La fonction "{0}" doit \u00EAtre appel\u00E9e directement et non par l''interm\u00E9diaire \ - d''une fonction portant un autre nom -msg.eval.nonstring=\ - Si vous appelez la fonction eval() avec une valeur qui n''est pas \u00E0 une cha\u00EEne primitive, \ - c''est la valeur en question qui est renvoy\u00E9e. \u00E9tait-ce votre intention? -msg.eval.nonstring.strict=\ - La fonction eval() ne peut \u00eatre appel\u00e9e avec une valeur autre qu'une cha\u00EEne primitive \ - en mode strict -msg.bad.destruct.op=\ - L''op\u00e9rateur de l''assignation d\u00e9structurante est incorrect -# NativeCall -msg.only.from.new=\ - {0} ne peut \u00EAtre appel\u00E9e qu''\u00E0 partir d''une "nouvelle" expression. -msg.deprec.ctor=\ - Le constructeur "{0}" est d\u00E9conseill\u00E9 -# NativeFunction -msg.no.function.ref.found=\ - aucune source n''a \u00E9t\u00E9 trouv\u00E9e pour d\u00E9compiler la r\u00E9f\u00E9rence de fonction {0} -msg.arg.isnt.array=\ - le second argument de la m\u00E9thode Function.prototype.apply doit \u00EAtre un tableau -# NativeGlobal -msg.bad.esc.mask=\ - le masque d''\u00E9chappement de cha\u00EEne est incorrect -# NativeJavaClass -msg.cant.instantiate=\ - erreur lors de l''instanciation ({0}): la classe {1} est une classe interface ou abstract -msg.bad.ctor.sig=\ - Un constructeur avec une signature incorrecte a \u00E9t\u00E9 d\u00E9tect\u00E9: \ - {0} qui appelle {1} avec la signature {2} -msg.not.java.obj=\ - L''argument attendu pour la fonction getClass() doit \u00EAtre un objet Java -msg.no.java.ctor=\ - Le constructeur Java de "{0}" avec les arguments "{1}" est introuvable -# NativeJavaMethod -msg.method.ambiguous=\ - Le choix de la m\u00E9thode Java {0}.{1} correspondant aux types d''argument JavaScript ({2}) est ambigu. \ - Les m\u00E9thodes propos\u00E9es sont les suivantes: {3} -msg.constructor.ambiguous=\ - Le choix du constructeur Java {0} correspondant aux types d''argument JavaScript ({1}) est ambigu. \ - Les constructeurs propos\u00E9s sont les suivants: {2} -# NativeJavaObject -msg.conversion.not.allowed=\ - Impossible de convertir {0} en {1} -msg.no.empty.interface.conversion=\ - Impossible de convertir la fonction en interface {0} sans aucune m\u00e9thode -msg.no.function.interface.conversion=\ - Impossible de convertir la fonction {0} en interface puisqu'elle contient des m\u00e9thodes avec \ - des noms diff\u00e9rentes -msg.undefined.function.interface=\ - La propri\u00E9t\u00E9 "{0}" n''est pas d\u00E9finie dans l''adaptateur d''interface -msg.not.function.interface=\ - La propri\u00E9t\u00E9 "{0}" n''est pas une fonction dans l''adaptateur d''interface -# NativeJavaPackage -msg.not.classloader=\ - Le constructeur de "Packages" attend un argument de type java.lang.Classloader -# NativeRegExp -msg.bad.quant=\ - Le quantificateur {0} est incorrect -msg.overlarge.backref=\ - La r\u00e9f\u00e9rence ant\u00e9rieure est trop importante {0} -msg.overlarge.min=\ - Le minimum {0} est trop important -msg.overlarge.max=\ - Le maximum {0} est trop important -msg.zero.quant=\ - Le quantificateur {0} est nul -msg.max.lt.min=\ - Le maximum {0} est inf\u00E9rieur au minimum -msg.unterm.quant=\ - Le quantificateur {0} n''a pas de limite -msg.unterm.paren=\ - Les parenth\u00E8ses {0} n''ont pas de limite -msg.unterm.class=\ - La classe de caract\u00E8res {0} n''a pas de limite -msg.bad.range=\ - La classe de caract\u00E8res contient une plage de valeurs incorrecte -msg.trail.backslash=\ - \\ \u00e0 la fin d''une expression rationnelle -msg.re.unmatched.right.paren=\ - Parenth\u00e8se fermante orpheline dans l'expression rationnelle -msg.no.regexp=\ - Les expressions rationnelles ne sont pas disponibles -msg.bad.backref=\ - la r\u00E9f\u00E9rence ant\u00E9rieure d\u00E9passe le nombre de parenth\u00E8ses de capture -msg.bad.regexp.compile=\ - Un seul argument peut \u00eatre sp\u00e9cifi\u00e9 si le premier argument de \ - RegExp.prototype.compile est un objet de type RegExp. -msg.arg.not.object=\ - L''argument attendu est de type ''object'' au lieu de ''{0}'' -# NativeDate -msg.invalid.date=\ - Date incorrecte. -msg.toisostring.must.return.primitive=\ - toISOString doit renvoyer une valeur primitive, mais a retourn\u00e9 \u00e0 la place "{0}" -# Parser -msg.got.syntax.errors=\ - La compilation a produit {0} erreur(s) de syntaxe. -msg.var.redecl=\ - Erreur de type: la variable "{0}" a \u00e9t\u00e9 de nouveau d\u00e9clar\u00e9e. -msg.const.redecl=\ - Erreur de type: la constante "{0}" a \u00e9t\u00e9 de nouveau d\u00e9clar\u00e9e. -msg.let.redecl=\ - Erreur de type: la variable "{0}" a \u00e9t\u00e9 de nouveau d\u00e9clar\u00e9e. -msg.parm.redecl=\ - Erreur de type: le param\u00e8tre formel "{0}" a \u00e9t\u00e9 de nouveau d\u00e9clar\u00e9. -msg.fn.redecl=\ - Erreur de type: la fonction "{0}" a \u00E9t\u00E9 de nouveau d\u00E9clar\u00E9e. -msg.let.decl.not.in.block=\ - Erreur de syntaxe: la d\u00e9claration ''let'' n''est pas directement dans un block -msg.bad.object.init=\ - Erreur de syntaxe: initialiseur d'objet incorrect -# NodeTransformer -msg.dup.label=\ - Le libell\u00E9 {0} existe d\u00E9j\u00E0 -msg.undef.label=\ - Le libell\u00E9 {0} n''est pas d\u00E9fini -msg.bad.break=\ - Le saut non libell\u00E9 doit se trouver dans une boucle ou un switch -msg.continue.outside=\ - continue doit se trouver dans la boucle -msg.continue.nonloop=\ - Il n''est possible de continuer que dans l''instruction d''it\u00E9ration libell\u00E9e -msg.bad.throw.eol=\ - Un retour \u00e0 la ligne n''est pas autoris\u00e9 entre un mot-clef throw et son \ - expression. -msg.no.paren.parms=\ - il manque ''('' avant les param\u00E8tres de la fonction -msg.no.parm=\ - il manque un param\u00E8tre formel -msg.no.paren.after.parms=\ - il manque '')'' apr\u00E8s les param\u00E8tres formels -msg.no.brace.body=\ - il manque ''{'' avant le corps d''une fonction -msg.no.brace.after.body=\ - il manque ''}'' apr\u00E8s le corps d''une fonction -msg.no.paren.cond=\ - il manque ''('' avant une condition -msg.no.paren.after.cond=\ - il manque '')'' apr\u00E8s une condition -msg.no.semi.stmt=\ - il manque '';'' avant une instruction -msg.missing.semi=\ - il manque '';'' apr\u00e8s une instruction -msg.no.name.after.dot=\ - il manque un nom apr\u00E8s un op\u00E9rateur ''.'' -msg.no.name.after.coloncolon=\ - il manque un nom apr\u00e8s un op\u00e9rateur ''::'' -msg.no.name.after.dotdot=\ - il manque un nom apr\u00e8s un op\u00e9rateur ''..'' -msg.no.name.after.xmlAttr=\ - il manque un nom apr\u00e8s ''.@'' -msg.no.bracket.index=\ - il manque '']'' dans l''expression de l''indice -msg.no.paren.switch=\ - il manque ''('' avant l''expression du switch -msg.no.paren.after.switch=\ - il manque '')'' apr\u00E8s l''expression du switch -msg.no.brace.switch=\ - il manque ''{'' avant le corps du switch -msg.bad.switch=\ - l''instruction switch est incorrecte -msg.no.colon.case=\ - il manque '':'' apr\u00E8s l''expression d''un cas -msg.double.switch.default=\ - le libell\u00e9 ''default'' appara\u00eet plusieurs fois dans le bloc switch -msg.no.while.do=\ - il manque ''while'' apr\u00E8s le corps d''une boucle do-loop -msg.no.paren.for=\ - il manque ''('' apr\u00E8s for -msg.no.semi.for=\ - Il manque '';'' apr\u00E8s l''initialiseur for-loop -msg.no.semi.for.cond=\ - il manque '';'' apr\u00E8s la condition for-loop -msg.in.after.for.name=\ - il manque le mot-clef ''in'' apr\u00e8s ''for'' -msg.no.paren.for.ctrl=\ - il manque '')'' apr\u00E8s le contr\u00f4le for-loop -msg.no.paren.with=\ - il manque ''('' avant un objet with-statement -msg.no.paren.after.with=\ - il manque '')'' apr\u00E8s un objet with-statement -msg.no.with.strict=\ - L'instruction with n''est pas autoris\u00e9e en mode strict -msg.no.paren.after.let=\ - il manque ''('' apr\u00e8s let -msg.no.paren.let=\ - il manque '')'' apr\u00e8s la liste de variables -msg.no.curly.let=\ - il manque ''}'' apr\u00e8s l'instruction let -msg.bad.return=\ - la valeur renvoy\u00E9e est incorrecte -msg.no.brace.block=\ - il manque ''}'' dans une instruction compos\u00E9e -msg.bad.label=\ - le libell\u00E9 est incorrect -msg.bad.var=\ - il manque un nom de variable -msg.bad.var.init=\ - l''initialisation de la variable est incorrecte -msg.no.colon.cond=\ - il manque '':'' dans une expression conditionnelle -msg.no.paren.arg=\ - il manque '')'' apr\u00E8s une liste d''arguments -msg.no.bracket.arg=\ - il manque '']'' apr\u00E8s une liste d''\u00E9l\u00E9ments -msg.bad.prop=\ - l''identifiant de propri\u00E9t\u00E9 est incorrect -msg.no.colon.prop=\ - il manque '':'' apr\u00E8s un identifiant de propri\u00E9t\u00E9 -msg.no.brace.prop=\ - il manque ''}'' apr\u00E8s une liste de propri\u00E9t\u00E9s -msg.no.paren=\ - il manque '')'' dans des parenth\u00E8ses -msg.reserved.id=\ - l''identifiant est un mot r\u00E9serv\u00E9 -msg.no.paren.catch=\ - il manque ''('' avant une condition catch-block -msg.bad.catchcond=\ - la condition catch-block est incorrecte -msg.catch.unreachable=\ - aucune clause catch suivant une interception non qualifi\u00E9e ne peut \u00EAtre atteinte -msg.no.brace.try=\ - il manque ''{'' avant le bloc try -msg.no.brace.catchblock=\ - il manque ''{'' avant le corps catch-block -msg.try.no.catchfinally=\ - ''try'' a \u00E9t\u00E9 d\u00E9tect\u00E9 sans ''catch'' ni ''finally'' -msg.no.return.value=\ - la fonction {0} ne renvoie pas toujours de valeur -msg.anon.no.return.value=\ - la fonction anonyme ne renvoie pas toujours de valeur -msg.return.inconsistent=\ - l'instruction return est incoh\u00e9rente avec les usages pr\u00e9c\u00e9dents -msg.generator.returns=\ - Erreur de type: la fonction g\u00e9n\u00e9ratrice {0} renvoie une valeur -msg.anon.generator.returns=\ - Erreur de type: la fonction g\u00e9n\u00e9ratrice anonyme renvoie une valeur -msg.syntax=\ - erreur de syntaxe -msg.unexpected.eof=\ - Fin de fichier inattendue -msg.XML.bad.form=\ - la syntaxe XML est mal form\u00e9e -msg.XML.not.available=\ - L''interpr\u00e9tation du XML n''est pas disponible -msg.too.deep.parser.recursion=\ - R\u00e9cursion trop profonde pendant l''analyse -msg.too.many.constructor.args=\ - Le constructeur a trop d''arguments -msg.too.many.function.args=\ - La fonction a trop d''arguments -msg.no.side.effects=\ - Le code n''a pas de valeur de retour -msg.extra.trailing.semi=\ - Point virgule superflux \u00e0 la fin -msg.extra.trailing.comma=\ - Une virgule \u00e0 la fin d''un initialiseur d''objet n''est pas autoris\u00e9 par le standard ECMA-262 -msg.trailing.array.comma=\ - Une virgule \u00e0 la fin d''un tableau lit\u00e9ral a un comportement diff\u00e9rent suivant le navigateur utilis\u00e9 -msg.equal.as.assign=\ - Le test d''\u00e9galit\u00e9 (==) a t''il \u00e9t\u00e9 saisi par erreur comme une assignation (=) ? -msg.var.hides.arg=\ - La variable {0} masque un argument -msg.destruct.assign.no.init=\ - Il manque ''='' dans l''assignation d\u00e9structurante -msg.no.octal.strict=\ - Les nombres octaux ne sont pas autoris\u00e9s en mode strict. -msg.dup.obj.lit.prop.strict=\ - La propri\u00e9t\u00e9 "{0}" est d\u00e9j\u00e0 d\u00e9finie dans cet objet lit\u00e9ral. -msg.dup.param.strict=\ - Le param\u00e8tre "{0}" est d\u00e9j\u00e0 d\u00e9clar\u00e9 dans cette fonction. -msg.bad.id.strict=\ - "{0}" n''est pas un identifiant valide pour cet usage en mode strict. -# ScriptRuntime -# is there a better message for this? -# it's currently only used as a poison pill for caller, caller and arguments properties -msg.op.not.allowed=\ - Cette op\u00e9ration n''est pas autoris\u00e9e. -msg.no.properties=\ - {0} n''a pas de propri\u00e9t\u00e9s. -msg.invalid.iterator=\ - La valeur n''est pas un it\u00e9rateur valide -msg.iterator.primitive=\ - __iterator__ a renvoy\u00e9 une valeur primitive -msg.assn.create.strict=\ - Assignation d''une variable non d\u00e9clar\u00e9e: {0} -msg.ref.undefined.prop=\ - R\u00e9f\u00e9rence \u00e0 une propri\u00e9t\u00e9 non d\u00e9finie "{0}" -msg.prop.not.found=\ - La propri\u00E9t\u00E9 est introuvable -msg.set.prop.no.setter=\ - Impossible de changer la propri\u00e9t\u00e9 ''{0}'' en l''absence de m\u00e9thode de d\u00e9finition. -msg.invalid.type=\ - Valeur JavaScript de type {0} incorrecte -msg.primitive.expected=\ - Un type primitif \u00E9tait attendu (et non {0}) -msg.namespace.expected=\ - Un espace de nom est attendu \u00e0 gauche de :: ({0} trouv\u00e9 \u00e0 la place) -msg.null.to.object=\ - Il est impossible de convertir la valeur null en objet -msg.undef.to.object=\ - Il est impossible de convertir une valeur non d\u00E9finie en objet -msg.cyclic.value=\ - La valeur cyclique {0} n''est pas autoris\u00E9e -msg.is.not.defined=\ - "{0}" n''est pas d\u00E9fini -msg.undef.prop.read=\ - Impossible de lire la propri\u00e9t\u00e9 "{1}" de {0} -msg.undef.prop.write=\ - Impossible de changer la propri\u00e9t\u00e9 "{1}" de {0} en "{2}" -msg.undef.prop.delete=\ - Impossible de supprimer la propri\u00e9t\u00e9 "{1}" de {0} -msg.undef.method.call=\ - Impossible d'appeler la m\u00e9thode "{1}" de {0} -msg.undef.with=\ - Impossible d'appliquer "with" \u00e0 {0} -msg.isnt.function=\ - {0} n''est pas une fonction, c''est un {1} -msg.isnt.function.in=\ - Impossible d'appeler la propri\u00e9t\u00e9 {0} de l'objet {1}. Ce n''est pas une fonction, c''est un "{2}". -msg.function.not.found=\ - Impossible de trouver la fonction {0}. -msg.function.not.found.in=\ - Impossible de trouver la fonction {0} dans l'objet {1}. -msg.isnt.xml.object=\ - {0} n''est pas un objet xml. -msg.no.ref.to.get=\ - {0} n''est pas une r\u00e9f\u00e9rence vers une m\u00e9thode d''obtention. -msg.no.ref.to.set=\ - {0} n''est pas une r\u00e9f\u00e9rence vers une m\u00e9thode de d\u00e9finition. -msg.no.ref.from.function=\ - La fonction {0} ne peut pas \u00eatre utilis\u00e9e comme la partie gauche de l''assignation \ - ou comme l'op\u00e9rande de l''op\u00e9rateur ++ ou --. -msg.bad.default.value=\ - La m\u00E9thode getDefaultValue() de l''objet a renvoy\u00E9 un objet -msg.instanceof.not.object=\ - Il est impossible d''utiliser une instance d''un \u00E9l\u00E9ment autre qu''un objet -msg.instanceof.bad.prototype=\ - La propri\u00E9t\u00E9 ''prototype'' de {0} n''est pas un objet -msg.in.not.object=\ - Il est impossible d''utiliser une instance d''un \u00E9l\u00E9ment autre qu''un objet -msg.bad.radix=\ - la base {0} n''est pas autoris\u00E9e -# ScriptableObject -msg.default.value=\ - La valeur par d\u00E9faut de l''objet est introuvable -msg.zero.arg.ctor=\ - Il est impossible de charger la classe "{0}", qui ne poss\u00E8de pas de constructeur de param\u00E8tre z\u00E9ro -duplicate.defineClass.name=\ - M\u00e9thode "{0}" incorrecte: le nom "{1}" est d\u00e9j\u00e0 utilis\u00e9. -msg.ctor.multiple.parms=\ - Il est impossible de d\u00E9finir le constructeur ou la classe {0} car plus d''un \ - constructeur poss\u00E8de plusieurs param\u00E8tres -msg.extend.scriptable=\ - {0} doit \u00E9tendre ScriptableObject afin de d\u00E9finir la propri\u00E9t\u00E9 {1} -msg.bad.getter.parms=\ - Pour d\u00E9finir une propri\u00E9t\u00E9, la m\u00E9thode d''obtention {0} doit avoir des param\u00E8tres z\u00E9ro \ - ou un seul param\u00E8tre ScriptableObject -msg.obj.getter.parms=\ - La m\u00E9thode d''obtention statique ou d\u00E9l\u00E9gu\u00E9e {0} doit utiliser un param\u00E8tre ScriptableObject -msg.getter.static=\ - La m\u00E9thode d''obtention et la m\u00E9thode de d\u00E9finition doivent toutes deux avoir le m\u00EAme \u00E9tat (statique ou non) -msg.setter.return=\ - La m\u00e9thode de d\u00e9finition doit avoir un type de retour vide: {0} -msg.setter2.parms=\ - La m\u00E9thode de d\u00E9finition \u00E0 deux param\u00E8tres doit utiliser un param\u00E8tre ScriptableObject comme premier param\u00E8tre -msg.setter1.parms=\ - Une m\u00E9thode d''obtention \u00E0 param\u00E8tre unique est attendue pour {0} -msg.setter2.expected=\ - La m\u00E9thode de d\u00E9finition statique ou d\u00E9l\u00E9gu\u00E9e {0} doit utiliser deux param\u00E8tres -msg.setter.parms=\ - Un ou deux param\u00E8tres sont attendus pour la m\u00E9thode de d\u00E9finition -msg.setter.bad.type=\ - Le type de param\u00e8tre "{0}" est incorrect dans la m\u00e9thode de d\u00e9finition "{1}". -msg.add.sealed=\ - Il est impossible d''ajouter une propri\u00E9t\u00E9 \u00E0 un objet scell\u00E9: {0}. -msg.remove.sealed=\ - Il est impossible de supprimer une propri\u00E9t\u00E9 d''un objet scell\u00E9: {0}. -msg.modify.sealed=\ - Il est impossible de modifier une propri\u00e9t\u00e9 d''un objet scell\u00E9: {0}. -msg.modify.readonly=\ - Il est impossible de modifier une propri\u00e9t\u00e9 en lecture seule: {0}. -msg.both.data.and.accessor.desc=\ - Le descripteur ne peut pas d\u00e9finir \u00e0 la fois un accesseur et une donn\u00e9e. -msg.change.configurable.false.to.true=\ - Impossible de changer de false \u00e0 true l''attribut ''configurable'' de "{0}". -msg.change.enumerable.with.configurable.false=\ - Impossible de changer l''attribut ''enumerable'' de "{0}" car ''configurable'' est ''false''. -msg.change.writable.false.to.true.with.configurable.false=\ - Impossible de changer de false \u00e0 true l''attribut ''writable'' de "{0}" car ''configurable'' est ''false''. -msg.change.value.with.writable.false=\ - Impossible de changer la valeur de l''attribut "{0}" car ''writable'' est ''false''. -msg.change.getter.with.configurable.false=\ - Impossible de changer l''attribut get de "{0}" car ''configurable'' est ''false''. -msg.change.setter.with.configurable.false=\ - Impossible de changer l''attribut set de "{0}" car ''configurable'' est ''false''. -msg.change.property.data.to.accessor.with.configurable.false=\ - Impossible de changer la propri\u00e9t\u00e9 par donn\u00e9e "{0}" en propri\u00e9t\u00e9 par accesseur car ''configurable'' est ''false'' -msg.change.property.accessor.to.data.with.configurable.false=\ - Impossible de changer la propri\u00e9t\u00e9 par accesseur "{0}" en propri\u00e9t\u00e9 par donn\u00e9e car ''configurable'' est ''false'' -msg.not.extensible=\ - Impossible d''ajouter des propri\u00e9t\u00e9s \u00e0 cet objet car ''extensible'' est ''false''. -# TokenStream -msg.missing.exponent=\ - il manque un exposant -msg.caught.nfe=\ - erreur de format de nombre: {0} -msg.unterminated.string.lit=\ - le litt\u00E9ral de la cha\u00EEne n''a pas de limite -msg.unterminated.comment=\ - le commentaire n''a pas de limite -msg.unterminated.re.lit=\ - le litt\u00E9ral de l''expression rationnelle n''a pas de limite -msg.invalid.re.flag=\ - une expression rationnelle est suivie d''un indicateur incorrect -msg.no.re.input.for=\ - il n''y a pas d''entr\u00E9e pour {0} -msg.illegal.character=\ - caract\u00E8re non autoris\u00E9 -msg.invalid.escape=\ - la s\u00E9quence d''\u00E9chappement Unicode est incorrecte -msg.bad.namespace=\ - L''instruction ''default xml namespace'' est incorrecte. \ - La syntaxe est: default xml namespace = EXPRESSION; -# TokensStream warnings -msg.bad.octal.literal=\ - le chiffre octal du litt\u00E9ral, {0}, n''est pas autoris\u00E9 et sera interpr\u00E9t\u00E9 comme un chiffre d\u00E9cimal -msg.reserved.keyword=\ - l''utilisation du futur mot-cl\u00E9 r\u00E9serv\u00E9 {0} n''est pas autoris\u00E9e et celui-ci sera interpr\u00E9t\u00E9 comme un identifiant ordinaire -# LiveConnect errors -msg.java.internal.field.type=\ - Erreur interne: la conversion de type de {0} afin d''affecter {1} \u00E0 {2} a \u00E9chou\u00E9 -msg.java.conversion.implicit_method=\ - La m\u00E9thode de conversion "{0}" est introuvable dans la classe {1} -msg.java.method.assign=\ - La m\u00E9thode Java "{0}" ne peut pas \u00EAtre affect\u00E9e \u00E0 -msg.java.internal.private=\ - Erreur interne: une tentative d''acc\u00E9der \u00E0 un champ "{0}" priv\u00E9/prot\u00E9g\u00E9 a \u00E9t\u00E9 d\u00E9tect\u00E9e -msg.java.no_such_method=\ - La m\u00E9thode ''{0}'' est introuvable -msg.script.is.not.constructor=\ - Les objets Script ne sont pas des constructeurs -msg.nonjava.method=\ - La m\u00E9thode Java "{0}" a \u00E9t\u00E9 appel\u00E9e avec une valeur ''this'' qui n''est pas un objet Java -msg.java.member.not.found=\ - La classe Java "{0}" ne poss\u00E8de aucun champ ou aucune m\u00E9thode d''instance publique appel\u00E9 "{1}" -msg.java.array.index.out.of.bounds=\ - L''indice {0} du tableau est en dehors de l''intervalle [0..{1}]. -msg.java.array.member.not.found=\ - Les tableaux Java n''ont pas de champs ou de m\u00e9thodes publiques "{0}". -msg.pkg.int=\ - Les noms de package Java ne peuvent pas \u00EAtre des nombres -msg.access.prohibited=\ - L''acc\u00e8s \u00e0 la classe Java "{0}" est prohib\u00e9. -# ImporterTopLevel -msg.ambig.import=\ - Importation ambigu\u00EB: "{0}" et "{1}" -msg.not.pkg=\ - La fonction importPackage doit \u00EAtre appel\u00E9e avec un package et non avec "{0}" -msg.not.class=\ - La fonction importClass doit \u00EAtre appel\u00E9e avec une classe et non avec "{0}" -msg.not.class.not.pkg=\ - "{0}" n''est ni une classe ni un package. -msg.prop.defined=\ - Il est impossible d''importer "{0}" car une propri\u00E9t\u00E9 portant le m\u00EAme nom a d\u00E9j\u00E0 \u00E9t\u00E9 d\u00E9finie -#JavaAdapter -msg.adapter.zero.args=\ - JavaAdapter n\u00e9cessite au moins un argument. -msg.not.java.class.arg=\ - L''argument {0} n''est pas une classe Java: {1}. -#JavaAdapter -msg.only.one.super=\ - Un JavaAdapter ne peut \u00e9tendre qu'une seule classe. Les classes {0} et {1} ont \u00e9t\u00e9 donn\u00e9es. -# Arrays -msg.arraylength.bad=\ - La longueur du tableau n''est pas appropri\u00E9e -# Arrays -msg.arraylength.too.big=\ - La longueur du tableau {0} d\u00e9passe la capacit\u00e9 limite. -msg.empty.array.reduce=\ - La m\u00e9thode ''reduce'' ne fonctionne pas sans valeur initiale sur un tableau vide -# URI -msg.bad.uri=\ - La s\u00E9quence URI n''est pas form\u00E9e correctement -# Number -msg.bad.precision=\ - La pr\u00E9cision {0} ne se trouve pas dans la plage de valeurs -# NativeGenerator -msg.send.newborn=\ - La m\u00e9thode send() d''un g\u00e9n\u00e9rateur ne peut \u00eatre appel\u00e9e avant un premier appel \u00e0 next() -msg.already.exec.gen=\ - Le g\u00e9n\u00e9rateur est d\u00e9j\u00e0 en cours d''ex\u00e9cution -msg.StopIteration.invalid=\ - L''exception StopIteration ne peut pas \u00eatre chang\u00e9e en un objet arbitraire. -# Interpreter -msg.yield.closing=\ - yield impossible quand le g\u00e9n\u00e9rateur est en train de se fermer diff --git a/common/src/main/resources/rhino-common.mixins.json b/common/src/main/resources/rhino-common.mixins.json index 35c6e785..9c5c06a2 100644 --- a/common/src/main/resources/rhino-common.mixins.json +++ b/common/src/main/resources/rhino-common.mixins.json @@ -4,7 +4,6 @@ "compatibilityLevel": "JAVA_17", "mixins": [ "ChatFormattingMixin", - "CollectionTagMixin", "CompoundTagMixin", "DirectionMixin", "DyeColorMixin", diff --git a/common/src/main/resources/rhino.accesswidener b/common/src/main/resources/rhino.accesswidener new file mode 100644 index 00000000..ecd72781 --- /dev/null +++ b/common/src/main/resources/rhino.accesswidener @@ -0,0 +1,3 @@ +accessWidener v2 named + +accessible field net/minecraft/nbt/CompoundTag tags Ljava/util/Map; \ No newline at end of file diff --git a/common/src/test/java/dev/latvian/mods/rhino/test/NBTTests.java b/common/src/test/java/dev/latvian/mods/rhino/test/NBTTests.java new file mode 100644 index 00000000..7c7731a4 --- /dev/null +++ b/common/src/test/java/dev/latvian/mods/rhino/test/NBTTests.java @@ -0,0 +1,41 @@ +package dev.latvian.mods.rhino.test; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class NBTTests { + public static RhinoTest TEST = new RhinoTest("nbt"); + + @Test + @DisplayName("Compound") + public void compound() { + TEST.test("compound", """ + let compoundTagTest = NBT.compoundTag() + + const testObject = { + a: -39, b: '2', c: 3439438.1 + } + + compoundTagTest.merge(testObject); + console.info(compoundTagTest) + """, """ + {a:-39.0d,b:"2",c:3439438.1d} + """); + } + + @Test + @DisplayName("List") + public void list() { + TEST.test("list", """ + let listTagTest = NBT.listTag() + + listTagTest.push('a') + listTagTest.push('b') + listTagTest.push('c') + + console.info(listTagTest) + """, """ + ["a","b","c"] + """); + } +} diff --git a/common/src/test/java/dev/latvian/mods/rhino/test/NullishCoalescingTests.java b/common/src/test/java/dev/latvian/mods/rhino/test/NullishCoalescingTests.java new file mode 100644 index 00000000..ca432fc4 --- /dev/null +++ b/common/src/test/java/dev/latvian/mods/rhino/test/NullishCoalescingTests.java @@ -0,0 +1,86 @@ +package dev.latvian.mods.rhino.test; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class NullishCoalescingTests { + public static RhinoTest TEST = new RhinoTest("nullishCoalescing"); + + @Test + @DisplayName("Both Non-Null") + public void bothNonNull() { + TEST.test("bothNonNull", """ + let a = 10 + let b = 20 + let c = a ?? b + console.info(c) + """, """ + 10.0 + """); + } + + @Test + @DisplayName("First Null") + public void firstNull() { + TEST.test("firstNull", """ + let a = null + let b = 20 + let c = a ?? b + console.info(c) + """, """ + 20.0 + """); + } + + @Test + @DisplayName("First Undefined") + public void firstUndefined() { + TEST.test("firstUndefined", """ + let a = undefined + let b = 20 + let c = a ?? b + console.info(c) + """, """ + 20.0 + """); + } + + @Test + @DisplayName("First False") + public void firstFalse() { + TEST.test("firstFalse", """ + let a = false + let b = 20 + let c = a ?? b + console.info(c) + """, """ + false + """); + } + + @Test + @DisplayName("First Zero") + public void firstZero() { + TEST.test("firstZero", """ + let a = 0 + let b = 20 + let c = a ?? b + console.info(c) + """, """ + 0.0 + """); + } + + @Test + @DisplayName("Second Null") + public void secondNull() { + TEST.test("secondNull", """ + let a = 10 + let b = null + let c = a ?? b + console.info(c) + """, """ + 10.0 + """); + } +} diff --git a/common/src/test/java/dev/latvian/mods/rhino/test/PowTests.java b/common/src/test/java/dev/latvian/mods/rhino/test/PowTests.java new file mode 100644 index 00000000..3b04b600 --- /dev/null +++ b/common/src/test/java/dev/latvian/mods/rhino/test/PowTests.java @@ -0,0 +1,73 @@ +package dev.latvian.mods.rhino.test; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class PowTests { + public static RhinoTest TEST = new RhinoTest("pow"); + + @Test + @DisplayName("Both Whole") + public void bothWhole() { + TEST.test("bothWhole", """ + let a = 10 + let b = 3 + let c = a ** b + console.info(c) + """, """ + 1000.0 + """); + } + + @Test + @DisplayName("Fraction Exponent") + public void fractionExponent() { + TEST.test("fractionExponent", """ + let a = 0.5 + let b = 0.5 + let c = a ** b + console.info(c) + """, """ + 0.7071067811865476 + """); + } + + @Test + @DisplayName("Fraction Base") + public void fractionBase() { + TEST.test("fractionBase", """ + let a = 2.5 + let b = 3 + let c = a ** b + console.info(c) + """, """ + 15.625 + """); + } + + @Test + @DisplayName("Zero Exponent") + public void zeroExponent() { + TEST.test("zeroExponent", """ + let a = 100 + let b = 0 + let c = a ** b + console.info(c) + """, """ + 1.0 + """); + } + + @Test + @DisplayName("Negative Exponent") + public void negativeExponent() { + TEST.test("negativeExponent", """ + let a = 400 + let b = -1 + let c = a ** b + console.info(c) + """, """ + 0.0025 + """); + } +} diff --git a/common/src/test/java/dev/latvian/mods/rhino/test/RhinoTest.java b/common/src/test/java/dev/latvian/mods/rhino/test/RhinoTest.java index 5d8f5e96..7039cd06 100644 --- a/common/src/test/java/dev/latvian/mods/rhino/test/RhinoTest.java +++ b/common/src/test/java/dev/latvian/mods/rhino/test/RhinoTest.java @@ -3,55 +3,65 @@ import dev.latvian.mods.rhino.Context; import dev.latvian.mods.rhino.NativeJavaClass; import dev.latvian.mods.rhino.ScriptableObject; +import dev.latvian.mods.rhino.mod.util.CollectionTagWrapper; +import dev.latvian.mods.rhino.mod.util.CompoundTagWrapper; import dev.latvian.mods.rhino.mod.util.NBTUtils; -import dev.latvian.mods.rhino.mod.util.NBTWrapper; +import net.minecraft.nbt.CollectionTag; import net.minecraft.nbt.CompoundTag; -import org.apache.commons.io.IOUtils; +import net.minecraft.nbt.Tag; +import org.junit.jupiter.api.Assertions; -import java.io.BufferedInputStream; -import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; public class RhinoTest { - public static void main(String[] args) { - var context = Context.enterWithNewFactory(); - // context.setClassShutter((fullClassName, type) -> type != ClassShutter.TYPE_CLASS_IN_PACKAGE || isClassAllowed(fullClassName)); + private static Context context; + + public static Context getContext() { + if (context != null) { + return context; + } - RhinoTest test = new RhinoTest(context); - test.add("console", TestConsole.class); - test.add("NBT", NBTWrapper.class); + context = Context.enterWithNewFactory(); + // context.setClassShutter((fullClassName, type) -> type != ClassShutter.TYPE_CLASS_IN_PACKAGE || isClassAllowed(fullClassName)); var typeWrappers = context.getTypeWrappers(); - typeWrappers.register(CompoundTag.class, o -> (CompoundTag) NBTUtils.toNBT(o)); + typeWrappers.register(CompoundTag.class, NBTUtils::toTagCompound); + typeWrappers.register(Tag.class, NBTUtils::toTag); - // test.load("/rhinotest/test.js"); - // test.load("/rhinotest/nbt.js"); - // test.load("/rhinotest/nullish_coalescing.js"); - // test.load("/rhinotest/pow.js"); - test.load("/rhinotest/units.js"); + context.addCustomJavaToJsWrapper(CompoundTag.class, CompoundTagWrapper::new); + context.addCustomJavaToJsWrapper(CollectionTag.class, CollectionTagWrapper::new); + + return context; } - public final Context context; - public final ScriptableObject scope; + public final String testName; + public final Map include; - public RhinoTest(Context c) { - context = c; - scope = context.initStandardObjects(); + public RhinoTest(String n) { + testName = n; + include = new HashMap<>(); + add("console", TestConsole.class); + add("NBT", NBTUtils.class); } - public void add(String name, Object value) { - if (value.getClass() == Class.class) { - ScriptableObject.putProperty(scope, name, new NativeJavaClass(scope, (Class) value)); - } else { - ScriptableObject.putProperty(scope, name, Context.javaToJS(value, scope)); - } + public RhinoTest add(String name, Object value) { + include.put(name, value); + return this; } - public void load(String file) { - try (var stream = RhinoTest.class.getResourceAsStream(file)) { - var script = new String(IOUtils.toByteArray(new BufferedInputStream(stream)), StandardCharsets.UTF_8); - context.evaluateString(scope, script, file, 1, null); - } catch (Throwable ex) { - ex.printStackTrace(); + public void test(String name, String script, String console) { + var scope = getContext().initStandardObjects(); + + for (var entry : include.entrySet()) { + if (entry.getValue() instanceof Class c) { + ScriptableObject.putProperty(scope, entry.getKey(), new NativeJavaClass(scope, c)); + } else { + ScriptableObject.putProperty(scope, entry.getKey(), Context.javaToJS(entry.getValue(), scope)); + } } + + getContext().evaluateString(scope, script, testName + "/" + name, 1, null); + Assertions.assertEquals(console.trim(), TestConsole.getConsoleOutput().trim()); } } diff --git a/common/src/test/java/dev/latvian/mods/rhino/test/TestConsole.java b/common/src/test/java/dev/latvian/mods/rhino/test/TestConsole.java index 3dba9481..a8982c77 100644 --- a/common/src/test/java/dev/latvian/mods/rhino/test/TestConsole.java +++ b/common/src/test/java/dev/latvian/mods/rhino/test/TestConsole.java @@ -1,5 +1,6 @@ package dev.latvian.mods.rhino.test; +import dev.latvian.mods.rhino.Context; import dev.latvian.mods.unit.UnitContext; import java.util.ArrayList; @@ -8,13 +9,45 @@ public class TestConsole { private static ConsoleTheme theme; + public static StringBuilder consoleOutput = new StringBuilder(); public static void info(Object o) { - System.out.println(o); + String s = String.valueOf(o); + + StringBuilder builder = new StringBuilder(); + + var lineP = new int[]{0}; + var lineS = Context.getSourcePositionFromStack(lineP); + + if (lineP[0] > 0) { + if (lineS != null) { + builder.append(lineS); + } + + builder.append(':'); + builder.append(lineP[0]); + builder.append(": "); + } + + builder.append(s); + + System.out.println(builder); + + if (consoleOutput.length() > 0) { + consoleOutput.append('\n'); + } + + consoleOutput.append(s); + } + + public static String getConsoleOutput() { + String s = consoleOutput.toString(); + consoleOutput.setLength(0); + return s; } - public static void freeze(Object[] objects) { - System.out.println("Freeze"); + public static void freeze(Object... objects) { + System.out.println("Freezing " + Arrays.toString(objects)); } public static String[] getTestArray() { diff --git a/common/src/test/java/dev/latvian/mods/rhino/test/UnitTests.java b/common/src/test/java/dev/latvian/mods/rhino/test/UnitTests.java index 7c6c78cd..5c6ee552 100644 --- a/common/src/test/java/dev/latvian/mods/rhino/test/UnitTests.java +++ b/common/src/test/java/dev/latvian/mods/rhino/test/UnitTests.java @@ -9,7 +9,6 @@ import java.util.Arrays; public class UnitTests { - public static double eval(String input) { return UnitContext.DEFAULT.parse(input).get(EmptyVariableSet.INSTANCE); } @@ -22,6 +21,28 @@ public static void assertEval(String input, double expected) { public static void assertStream(String input, String... expected) { Assertions.assertEquals(Arrays.asList(expected), UnitContext.DEFAULT.createStream(input).toTokenStrings()); } + /* Tests that still need to be written: +// simple eq +console.printUnit('5==5.0') +console.printUnit('5 == 5.0') + +// functions +console.printUnit('sin($test*10)*5') +console.printUnit('$test<0.5?-30:40') +console.printUnit('($test<0.5?($test2<0.5?1.5:-4):($test3<0.5*-3?1.5:-4))') +console.printUnit('(sin((time() * 1.1)) * (($screenW - 32) / 2))') + +// test sub vs negate +console.printUnit('-2') +console.printUnit('2 - 2') +console.printUnit('-2 - 2') +console.printUnit('2 - --2') +console.printUnit('- (2**7) - (-2)') + +// color +console.printUnit('#FF0044') +console.printUnit('#FFFF0044') + */ @Test @DisplayName("Ternary Token Stream") @@ -29,10 +50,10 @@ public void testTernaryTokenStream() { assertStream("0 < 5 ? 1.5 : 2", "0.0", "<", "5.0", "?", "1.5", ":", "2.0"); } - @Test + // @Test @DisplayName("Order of operations") public void testOrderOfOperations() { - assertEval("4 - (2 + 8*2 - 1) / 5", 0.6); + assertEval("4 - (2 + 8* 2 - 1) / 5", 0.6); } @Test diff --git a/common/src/test/resources/rhinotest/nbt.js b/common/src/test/resources/rhinotest/nbt.js deleted file mode 100644 index c35b9bca..00000000 --- a/common/src/test/resources/rhinotest/nbt.js +++ /dev/null @@ -1,20 +0,0 @@ -// Compound tag - -let compoundTagTest = NBT.compoundTag() - -const testObject = { - a: -39, b: '2', c: 3439438 -} - -compoundTagTest.merge(testObject); -console.info(compoundTagTest) - -// List tag - -let listTagTest = NBT.listTag() - -listTagTest.push('a') -listTagTest.push('b') -listTagTest.push('c') - -console.info(listTagTest) diff --git a/common/src/test/resources/rhinotest/nullish_coalescing.js b/common/src/test/resources/rhinotest/nullish_coalescing.js deleted file mode 100644 index 2a879818..00000000 --- a/common/src/test/resources/rhinotest/nullish_coalescing.js +++ /dev/null @@ -1,49 +0,0 @@ -console.info('Nullish Coalescing Operator Test') - -// Should print 10 -{ - let a = 10 - let b = 20 - let c = a ?? b - console.info(c) -} - -// Should print 20 -{ - let a = null - let b = 20 - let c = a ?? b - console.info(c) -} - -// Should print 20 -{ - let a = undefined - let b = 20 - let c = a ?? b - console.info(c) -} - -// Should print false -{ - let a = false - let b = 20 - let c = a ?? b - console.info(c) -} - -// Should print 0 -{ - let a = 0 - let b = 20 - let c = a ?? b - console.info(c) -} - -// Should print 10 -{ - let a = 10 - let b = null - let c = a ?? b - console.info(c) -} \ No newline at end of file diff --git a/common/src/test/resources/rhinotest/pow.js b/common/src/test/resources/rhinotest/pow.js deleted file mode 100644 index d968dc11..00000000 --- a/common/src/test/resources/rhinotest/pow.js +++ /dev/null @@ -1,25 +0,0 @@ -console.info('Pow Test') - -// Should print 0.70710678118 -{ - let a = 0.5 - let b = 0.5 - let c = a ** b - console.info(c) -} - -// Should print 15.625 -{ - let a = 2.5 - let b = 3 - let c = a ** b - console.info(c) -} - -// Should print 1.0 -{ - let a = 100 - let b = 0 - let c = a ** b - console.info(c) -} \ No newline at end of file diff --git a/common/src/test/resources/rhinotest/units.js b/common/src/test/resources/rhinotest/units.js deleted file mode 100644 index 0e1659f1..00000000 --- a/common/src/test/resources/rhinotest/units.js +++ /dev/null @@ -1,17 +0,0 @@ -// simple eq -console.printUnit('5==5.0') -console.printUnit('5 == 5.0') -// functions -console.printUnit('sin($test*10)*5') -console.printUnit('$test<0.5?-30:40') -console.printUnit('($test<0.5?($test2<0.5?1.5:-4):($test3<0.5*-3?1.5:-4))') -console.printUnit('(sin((time() * 1.1)) * (($screenW - 32) / 2))') -// test sub vs negate -console.printUnit('-2') -console.printUnit('2 - 2') -console.printUnit('-2 - 2') -console.printUnit('2 - --2') -console.printUnit('- (2**7) - (-2)') -// color -console.printUnit('#FF0044') -console.printUnit('#FFFF0044') \ No newline at end of file diff --git a/fabric/build.gradle b/fabric/build.gradle index 26035c0b..4c26ac2d 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -64,11 +64,9 @@ if (ENV.CURSEFORGE_KEY) { curseforge { apiKey = ENV.CURSEFORGE_KEY project { - id = project.curseforge_id_fabric + id = project.curseforge_id releaseType = project.curseforge_type addGameVersion "Fabric" - addGameVersion "1.18" - addGameVersion "1.18.1" addGameVersion "1.18.2" mainArtifact(remapJar.archivePath) changelog = getGitChangelog diff --git a/forge/build.gradle b/forge/build.gradle index 228536f4..59dd97ae 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -84,11 +84,9 @@ if (ENV.CURSEFORGE_KEY) { curseforge { apiKey = ENV.CURSEFORGE_KEY project { - id = project.curseforge_id_forge + id = project.curseforge_id releaseType = project.curseforge_type addGameVersion "Forge" - addGameVersion "1.18" - addGameVersion "1.18.1" addGameVersion "1.18.2" mainArtifact(remapJar.archivePath) changelog = getGitChangelog diff --git a/gradle.properties b/gradle.properties index 1f72d06a..51697c46 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,11 +3,10 @@ org.gradle.daemon=false mod_id=rhino archives_base_name=rhino maven_group=dev.latvian.mods -mod_version=1801.1.9 +mod_version=1802.1.10 mod_author=LatvianModder -curseforge_id_forge=416294 -curseforge_id_fabric=416294 -curseforge_type=beta -minecraft_version=1.18.1 -fabric_loader_version=0.12.6 -forge_version=39.0.+ \ No newline at end of file +curseforge_id=416294 +curseforge_type=release +minecraft_version=1.18.2 +fabric_loader_version=0.13.3 +forge_version=40.1.0 \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 242005c5..256e3035 100644 --- a/settings.gradle +++ b/settings.gradle @@ -2,6 +2,7 @@ pluginManagement { repositories { maven { url "https://maven.creeperhost.net/" } maven { url "https://maven.architectury.dev/" } + maven { url "https://server.bbkr.space/artifactory/libs-release/" } gradlePluginPortal() } }