mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -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) {
|
} else if (from instanceof ValueType.Primitive && to instanceof ValueType.Object) {
|
||||||
String primitiveClass = ((ValueType.Object) to).getClassName();
|
String primitiveClass = ((ValueType.Object) to).getClassName();
|
||||||
PrimitiveType toType = getWrappedPrimitive(primitiveClass);
|
PrimitiveType toType = getWrappedPrimitive(primitiveClass);
|
||||||
|
var fromType = (ValueType.Primitive) from;
|
||||||
if (toType == null) {
|
if (toType == null) {
|
||||||
return arg;
|
return arg.getProgramEmitter().invoke(fromType.getBoxedType().getClassName(), "valueOf",
|
||||||
|
fromType.getBoxedType(), arg);
|
||||||
}
|
}
|
||||||
arg = tryConvertArgument(arg, from, ValueType.primitive(toType));
|
arg = tryConvertArgument(arg, from, ValueType.primitive(toType));
|
||||||
return arg.getProgramEmitter().invoke(primitiveClass, "valueOf", to, arg);
|
return arg.getProgramEmitter().invoke(primitiveClass, "valueOf", to, arg);
|
||||||
} else if (from instanceof ValueType.Object && to instanceof ValueType.Primitive) {
|
} else if (from instanceof ValueType.Object && to instanceof ValueType.Primitive) {
|
||||||
String primitiveClass = ((ValueType.Object) from).getClassName();
|
var fromClass = ((ValueType.Object) from).getClassName();
|
||||||
PrimitiveType fromType = getWrappedPrimitive(primitiveClass);
|
var primitiveType = (ValueType.Primitive) to;
|
||||||
if (fromType == null) {
|
if (fromClass.equals("java.lang.Object")) {
|
||||||
return arg;
|
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 {
|
} else {
|
||||||
return arg.cast(to);
|
return arg.cast(to);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,15 @@ package org.teavm.vm;
|
||||||
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.IntPredicate;
|
import java.util.function.IntPredicate;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
import java.util.function.ToDoubleFunction;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.teavm.junit.EachTestCompiledSeparately;
|
import org.teavm.junit.EachTestCompiledSeparately;
|
||||||
|
@ -80,6 +83,31 @@ public class LambdaTest {
|
||||||
Consumer<String> foo = bar -> { };
|
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) {
|
private String acceptIntPredicate(IntPredicate p) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user