diff --git a/src/main/java/dev/latvian/mods/rhino/type/RecordTypeInfo.java b/src/main/java/dev/latvian/mods/rhino/type/RecordTypeInfo.java index 810ddded..e7e97db3 100644 --- a/src/main/java/dev/latvian/mods/rhino/type/RecordTypeInfo.java +++ b/src/main/java/dev/latvian/mods/rhino/type/RecordTypeInfo.java @@ -16,6 +16,7 @@ import java.util.IdentityHashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.function.Consumer; public class RecordTypeInfo extends ClassTypeInfo implements TypeWrapperFactory { @@ -49,6 +50,10 @@ public Data getData() { components[i] = c; componentMap.put(c.name, c); defaultArguments[i] = c.type.createDefaultValue(); + + if (c.type.is(TypeInfo.RAW_OPTIONAL)) { + defaultArguments[i] = Optional.empty(); + } } data = new Data(components, Map.copyOf(componentMap), defaultArguments); @@ -127,7 +132,11 @@ public Object createInstance(Context cx, Map map) { var c = data.componentMap.get(String.valueOf(entry.getKey())); if (c != null) { - args[c.index] = cx.jsToJava(entry.getValue(), c.type); + if (args[c.index] == Optional.empty()) { + args[c.index] = Optional.ofNullable(cx.jsToJava(entry.getValue(), c.type.param(0))); + } else { + args[c.index] = cx.jsToJava(entry.getValue(), c.type); + } } } @@ -147,7 +156,11 @@ public Object createInstance(Context cx, Object... objects) { int alen = Math.min(args.length, objects.length); for (int i = 0; i < alen; i++) { - args[i] = cx.jsToJava(objects[i], data.components[i].type); + if (args[i] == Optional.empty()) { + args[i] = Optional.ofNullable(cx.jsToJava(objects[i], data.components[i].type.param(0))); + } else { + args[i] = cx.jsToJava(objects[i], data.components[i].type); + } } try { diff --git a/src/main/java/dev/latvian/mods/rhino/type/TypeInfo.java b/src/main/java/dev/latvian/mods/rhino/type/TypeInfo.java index b308a594..a50eccc6 100644 --- a/src/main/java/dev/latvian/mods/rhino/type/TypeInfo.java +++ b/src/main/java/dev/latvian/mods/rhino/type/TypeInfo.java @@ -11,6 +11,7 @@ import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.function.Consumer; import java.util.function.Function; @@ -60,6 +61,7 @@ public interface TypeInfo { TypeInfo RAW_LIST = new InterfaceTypeInfo(List.class, Boolean.FALSE); TypeInfo RAW_SET = new InterfaceTypeInfo(Set.class, Boolean.FALSE); TypeInfo RAW_MAP = new InterfaceTypeInfo(Map.class, Boolean.FALSE); + TypeInfo RAW_OPTIONAL = new BasicClassTypeInfo(Optional.class); Class asClass(); @@ -126,6 +128,8 @@ static TypeInfo of(Class c) { return CLASS; } else if (c == Date.class) { return DATE; + } else if (c == Optional.class) { + return RAW_OPTIONAL; } else if (c == Runnable.class) { return RUNNABLE; } else if (c == Consumer.class) { diff --git a/src/test/java/dev/latvian/mods/rhino/test/RecordTests.java b/src/test/java/dev/latvian/mods/rhino/test/RecordTests.java index abfc50a6..ea0297dd 100644 --- a/src/test/java/dev/latvian/mods/rhino/test/RecordTests.java +++ b/src/test/java/dev/latvian/mods/rhino/test/RecordTests.java @@ -14,7 +14,7 @@ public void emptyObject() { TEST.test("emptyObject", """ console.printRecord({}) """, """ - TestRecord[num=0, str=null, sub=null] + TestRecord[num=0, str=Optional.empty, sub=null] """); } @@ -23,7 +23,7 @@ public void object() { TEST.test("object", """ console.printRecord({str: 'hello'}) """, """ - TestRecord[num=0, str=hello, sub=null] + TestRecord[num=0, str=Optional[hello], sub=null] """); } @@ -32,7 +32,7 @@ public void objectWithSub() { TEST.test("objectWithSub", """ console.printRecord({sub: {num: 5}}) """, """ - TestRecord[num=0, str=null, sub=TestRecord[num=5, str=null, sub=null]] + TestRecord[num=0, str=Optional.empty, sub=TestRecord[num=5, str=Optional.empty, sub=null]] """); } @@ -41,7 +41,7 @@ public void consumer() { TEST.test("object", """ console.printRecord(r => { r.str = 'hello' }) """, """ - TestRecord[num=0, str=hello, sub=null] + TestRecord[num=0, str=Optional[hello], sub=null] """); } @@ -50,7 +50,7 @@ public void array() { TEST.test("object", """ console.printRecord([5, 'hi']) """, """ - TestRecord[num=5, str=hi, sub=null] + TestRecord[num=5, str=Optional[hi], sub=null] """); } @@ -59,7 +59,7 @@ public void mix() { TEST.test("object", """ console.printRecord([5, 'hi', r => r.sub = {num: -50}]) """, """ - TestRecord[num=5, str=hi, sub=TestRecord[num=0, str=null, sub=TestRecord[num=-50, str=null, sub=null]]] + TestRecord[num=5, str=Optional[hi], sub=TestRecord[num=0, str=Optional.empty, sub=TestRecord[num=-50, str=Optional.empty, sub=null]]] """); } } diff --git a/src/test/java/dev/latvian/mods/rhino/test/TestRecord.java b/src/test/java/dev/latvian/mods/rhino/test/TestRecord.java index 547ce5f5..5f7d4224 100644 --- a/src/test/java/dev/latvian/mods/rhino/test/TestRecord.java +++ b/src/test/java/dev/latvian/mods/rhino/test/TestRecord.java @@ -1,4 +1,6 @@ package dev.latvian.mods.rhino.test; -public record TestRecord(int num, String str, TestRecord sub) { +import java.util.Optional; + +public record TestRecord(int num, Optional str, TestRecord sub) { }