Skip to content

Commit b8d4e02

Browse files
committed
8255374: Add a dropReturn MethodHandle combinator
Reviewed-by: redestad
1 parent 1d0bd50 commit b8d4e02

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

src/java.base/share/classes/java/lang/invoke/MethodHandles.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
import java.util.stream.Collectors;
6363
import java.util.stream.Stream;
6464

65+
import static java.lang.invoke.LambdaForm.BasicType.V_TYPE;
6566
import static java.lang.invoke.MethodHandleImpl.Intrinsic;
6667
import static java.lang.invoke.MethodHandleNatives.Constants.*;
6768
import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
@@ -5205,6 +5206,28 @@ public static MethodHandle dropArgumentsToMatch(MethodHandle target, int skip, L
52055206
return dropArgumentsToMatch(target, skip, newTypes, pos, false);
52065207
}
52075208

5209+
/**
5210+
* Drop the return value of the target handle (if any).
5211+
* The returned method handle will have a {@code void} return type.
5212+
*
5213+
* @param target the method handle to adapt
5214+
* @return a possibly adapted method handle
5215+
* @throws NullPointerException if {@code target} is null
5216+
* @since 16
5217+
*/
5218+
public static MethodHandle dropReturn(MethodHandle target) {
5219+
Objects.requireNonNull(target);
5220+
MethodType oldType = target.type();
5221+
Class<?> oldReturnType = oldType.returnType();
5222+
if (oldReturnType == void.class)
5223+
return target;
5224+
MethodType newType = oldType.changeReturnType(void.class);
5225+
BoundMethodHandle result = target.rebind();
5226+
LambdaForm lform = result.editor().filterReturnForm(V_TYPE, true);
5227+
result = result.copyWith(newType, lform);
5228+
return result;
5229+
}
5230+
52085231
/**
52095232
* Adapts a target method handle by pre-processing
52105233
* one or more of its arguments, each with its own unary filter function,
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8255398
27+
* @run testng TestDropReturn
28+
*/
29+
30+
import org.testng.annotations.DataProvider;
31+
import org.testng.annotations.Test;
32+
33+
import java.lang.invoke.MethodHandle;
34+
import java.lang.invoke.MethodHandles;
35+
36+
import static java.lang.invoke.MethodType.methodType;
37+
import static org.testng.Assert.assertEquals;
38+
39+
public class TestDropReturn {
40+
41+
@Test(dataProvider = "dropReturnCases")
42+
public void testDropReturn(Class<?> cls, Object testValue) throws Throwable {
43+
MethodHandle mh = MethodHandles.identity(cls);
44+
assertEquals(mh.type(), methodType(cls, cls));
45+
Object x = mh.invoke(testValue);
46+
assertEquals(x, testValue);
47+
48+
mh = MethodHandles.dropReturn(mh);
49+
assertEquals(mh.type(), methodType(void.class, cls));
50+
mh.invoke(testValue); // should at least work
51+
}
52+
53+
@DataProvider
54+
public static Object[][] dropReturnCases() {
55+
return new Object[][]{
56+
{ boolean.class, true },
57+
{ byte.class, (byte) 10 },
58+
{ char.class, 'x' },
59+
{ short.class, (short) 10 },
60+
{ int.class, 10 },
61+
{ long.class, 10L },
62+
{ float.class, 10F },
63+
{ double.class, 10D },
64+
{ Object.class, new Object() },
65+
{ String.class, "ABCD" },
66+
};
67+
}
68+
}

0 commit comments

Comments
 (0)