mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Fix boxing/unboxing arguments and return values in method references
This commit is contained in:
parent
4fc43a5597
commit
318d4bff93
|
@ -188,19 +188,35 @@ public class LambdaMetafactorySubstitutor implements BootstrapMethodSubstitutor
|
|||
} else if (from instanceof ValueType.Primitive && to instanceof ValueType.Object) {
|
||||
String primitiveClass = ((ValueType.Object) to).getClassName();
|
||||
PrimitiveType toType = getWrappedPrimitive(primitiveClass);
|
||||
var fromType = (ValueType.Primitive) from;
|
||||
if (toType == null) {
|
||||
return arg;
|
||||
return arg.getProgramEmitter().invoke(fromType.getBoxedType().getClassName(), "valueOf",
|
||||
fromType.getBoxedType(), arg);
|
||||
}
|
||||
arg = tryConvertArgument(arg, from, ValueType.primitive(toType));
|
||||
return arg.getProgramEmitter().invoke(primitiveClass, "valueOf", to, arg);
|
||||
} else if (from instanceof ValueType.Object && to instanceof ValueType.Primitive) {
|
||||
String primitiveClass = ((ValueType.Object) from).getClassName();
|
||||
PrimitiveType fromType = getWrappedPrimitive(primitiveClass);
|
||||
if (fromType == null) {
|
||||
return arg;
|
||||
var fromClass = ((ValueType.Object) from).getClassName();
|
||||
var primitiveType = (ValueType.Primitive) to;
|
||||
if (fromClass.equals("java.lang.Object")) {
|
||||
switch (primitiveType.getKind()) {
|
||||
case BYTE:
|
||||
case SHORT:
|
||||
case INTEGER:
|
||||
case LONG:
|
||||
case FLOAT:
|
||||
case DOUBLE:
|
||||
arg = arg.cast(ValueType.object("java.lang.Number"));
|
||||
break;
|
||||
case BOOLEAN:
|
||||
arg = arg.cast(ValueType.object("java.lang.Boolean"));
|
||||
break;
|
||||
case CHARACTER:
|
||||
arg = arg.cast(ValueType.object("java.lang.Character"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
arg = arg.invokeVirtual(primitiveName(fromType) + "Value", ValueType.primitive(fromType));
|
||||
return tryConvertArgument(arg, ValueType.primitive(fromType), to);
|
||||
return arg.invokeVirtual(primitiveName(primitiveType.getKind()) + "Value", primitiveType);
|
||||
} else {
|
||||
return arg.cast(to);
|
||||
}
|
||||
|
|
|
@ -17,12 +17,15 @@ package org.teavm.vm;
|
|||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.IntPredicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.ToDoubleFunction;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.teavm.junit.EachTestCompiledSeparately;
|
||||
|
@ -80,6 +83,31 @@ public class LambdaTest {
|
|||
Consumer<String> foo = bar -> { };
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodReferenceUnboxing() {
|
||||
var map = Map.of(1, 23.0, 2, 42.0);
|
||||
ToDoubleFunction<Integer> f = map::get;
|
||||
assertEquals(23.0, f.applyAsDouble(1), 0.01);
|
||||
assertNotEquals(24.0, f.applyAsDouble(1), 0.01);
|
||||
assertEquals(42.0, f.applyAsDouble(2), 0.01);
|
||||
|
||||
var intMap = Map.of(1, 23, 2, 42);
|
||||
ToDoubleFunction<Integer> g = intMap::get;
|
||||
assertEquals(23.0, g.applyAsDouble(1), 0.01);
|
||||
assertNotEquals(24.0, g.applyAsDouble(1), 0.01);
|
||||
assertEquals(42.0, g.applyAsDouble(2), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodReferenceBoxing() {
|
||||
java.util.function.Function<Integer, Object> f = this::intFunction;
|
||||
assertEquals(25, f.apply(23));
|
||||
}
|
||||
|
||||
private int intFunction(int a) {
|
||||
return a + 2;
|
||||
}
|
||||
|
||||
private String acceptIntPredicate(IntPredicate p) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user