test/tools/javac/lambda/lambdaExecution/LambdaTranslationTest2.java

Tue, 14 May 2013 11:11:09 -0700

author
rfield
date
Tue, 14 May 2013 11:11:09 -0700
changeset 1752
c09b7234cded
parent 0
959103a6100f
permissions
-rw-r--r--

8012556: Implement lambda methods on interfaces as static
8006140: Javac NPE compiling Lambda expression on initialization expression of static field in interface
Summary: Lambdas occurring in static contexts or those not needing instance information should be generated into static methods. This has long been the case for classes. However, as a work-around to the lack of support for statics on interfaces, interface lambda methods have been generated into default methods. For lambdas in interface static contexts (fields and static methods) this causes an NPE in javac because there is no 'this'. MethodHandles now support static methods on interfaces. This changeset allows lambda methods to be generated as static interface methods. An existing bug in Hotspot (8013875) is exposed in a test when the "-esa" flag is used. This test and another test that already exposed this bug have been marked with @ignore.
Reviewed-by: mcimadamore

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 /**
aoqi@0 27 * @test
aoqi@0 28 * @bug 8003639
aoqi@0 29 * @summary convert lambda testng tests to jtreg and add them
aoqi@0 30 * @run testng LambdaTranslationTest2
aoqi@0 31 */
aoqi@0 32
aoqi@0 33 import org.testng.annotations.Test;
aoqi@0 34
aoqi@0 35 import java.util.ArrayList;
aoqi@0 36 import java.util.List;
aoqi@0 37
aoqi@0 38 import static org.testng.Assert.assertEquals;
aoqi@0 39 import static org.testng.Assert.assertTrue;
aoqi@0 40
aoqi@0 41 /**
aoqi@0 42 * LambdaTranslationTest2 -- end-to-end smoke tests for lambda evaluation
aoqi@0 43 */
aoqi@0 44
aoqi@0 45 @Test
aoqi@0 46 public class LambdaTranslationTest2 {
aoqi@0 47
aoqi@0 48 final String dummy = "dummy";
aoqi@0 49
aoqi@0 50 public void testLambdas() {
aoqi@0 51 TPredicate<String> isEmpty = s -> s.isEmpty();
aoqi@0 52 assertTrue(isEmpty.test(""));
aoqi@0 53 assertTrue(!isEmpty.test("foo"));
aoqi@0 54
aoqi@0 55 TPredicate<Object> oIsEmpty = s -> ((String) s).isEmpty();
aoqi@0 56 assertTrue(oIsEmpty.test(""));
aoqi@0 57 assertTrue(!oIsEmpty.test("foo"));
aoqi@0 58
aoqi@0 59 TPredicate<Object> alwaysTrue = o -> true;
aoqi@0 60 assertTrue(alwaysTrue.test(""));
aoqi@0 61 assertTrue(alwaysTrue.test(null));
aoqi@0 62
aoqi@0 63 TPredicate<Object> alwaysFalse = o -> false;
aoqi@0 64 assertTrue(!alwaysFalse.test(""));
aoqi@0 65 assertTrue(!alwaysFalse.test(null));
aoqi@0 66
aoqi@0 67 // tests local capture
aoqi@0 68 String foo = "foo";
aoqi@0 69 TPredicate<String> equalsFoo = s -> s.equals(foo);
aoqi@0 70 assertTrue(!equalsFoo.test(""));
aoqi@0 71 assertTrue(equalsFoo.test("foo"));
aoqi@0 72
aoqi@0 73 // tests instance capture
aoqi@0 74 TPredicate<String> equalsDummy = s -> s.equals(dummy);
aoqi@0 75 assertTrue(!equalsDummy.test(""));
aoqi@0 76 assertTrue(equalsDummy.test("dummy"));
aoqi@0 77
aoqi@0 78 TMapper<Object, Object> ident = s -> s;
aoqi@0 79
aoqi@0 80 assertEquals("blarf", ident.map("blarf"));
aoqi@0 81 assertEquals("wooga", ident.map("wooga"));
aoqi@0 82 assertTrue("wooga" == ident.map("wooga"));
aoqi@0 83
aoqi@0 84 // constant capture
aoqi@0 85 TMapper<Object, Object> prefixer = s -> "p" + s;
aoqi@0 86 assertEquals("pblarf", prefixer.map("blarf"));
aoqi@0 87 assertEquals("pwooga", prefixer.map("wooga"));
aoqi@0 88
aoqi@0 89 // instance capture
aoqi@0 90 TMapper<Object, Object> prefixer2 = s -> dummy + s;
aoqi@0 91 assertEquals("dummyblarf", prefixer2.map("blarf"));
aoqi@0 92 assertEquals("dummywooga", prefixer2.map("wooga"));
aoqi@0 93 }
aoqi@0 94
aoqi@0 95 interface Factory<T> {
aoqi@0 96 T make();
aoqi@0 97 }
aoqi@0 98
aoqi@0 99 interface StringFactory extends Factory<String> { }
aoqi@0 100
aoqi@0 101 interface StringFactory2 extends Factory<String> {
aoqi@0 102 String make();
aoqi@0 103 }
aoqi@0 104
aoqi@0 105 public void testBridges() {
aoqi@0 106 Factory<String> of = () -> "y";
aoqi@0 107 Factory<?> ef = () -> "z";
aoqi@0 108
aoqi@0 109 assertEquals("y", of.make());
aoqi@0 110 assertEquals("y", ((Factory<?>) of).make());
aoqi@0 111 assertEquals("y", ((Factory) of).make());
aoqi@0 112
aoqi@0 113 assertEquals("z", ef.make());
aoqi@0 114 assertEquals("z", ((Factory) ef).make());
aoqi@0 115 }
aoqi@0 116
aoqi@0 117 public void testBridgesImplicitSpecialization() {
aoqi@0 118 StringFactory sf = () -> "x";
aoqi@0 119
aoqi@0 120 assertEquals("x", sf.make());
aoqi@0 121 assertEquals("x", ((Factory<String>) sf).make());
aoqi@0 122 assertEquals("x", ((Factory<?>) sf).make());
aoqi@0 123 assertEquals("x", ((Factory) sf).make());
aoqi@0 124 }
aoqi@0 125
aoqi@0 126 public void testBridgesExplicitSpecialization() {
aoqi@0 127 StringFactory2 sf = () -> "x";
aoqi@0 128
aoqi@0 129 assertEquals("x", sf.make());
aoqi@0 130 assertEquals("x", ((Factory<String>) sf).make());
aoqi@0 131 assertEquals("x", ((Factory<?>) sf).make());
aoqi@0 132 assertEquals("x", ((Factory) sf).make());
aoqi@0 133 }
aoqi@0 134
aoqi@0 135 public void testSuperCapture() {
aoqi@0 136 class A {
aoqi@0 137 String make() { return "x"; }
aoqi@0 138 }
aoqi@0 139
aoqi@0 140 class B extends A {
aoqi@0 141 void testSuperCapture() {
aoqi@0 142 StringFactory sf = () -> super.make();
aoqi@0 143 assertEquals("x", sf.make());
aoqi@0 144 }
aoqi@0 145 }
aoqi@0 146
aoqi@0 147 new B().testSuperCapture();
aoqi@0 148 }
aoqi@0 149
aoqi@0 150 interface WidenD {
aoqi@0 151 public String m(float a0, double a1);
aoqi@0 152 }
aoqi@0 153
aoqi@0 154 interface WidenS {
aoqi@0 155 public String m(byte a0, short a1);
aoqi@0 156 }
aoqi@0 157
aoqi@0 158 interface WidenI {
aoqi@0 159 public String m(byte a0, short a1, char a2, int a3);
aoqi@0 160 }
aoqi@0 161
aoqi@0 162 interface WidenL {
aoqi@0 163 public String m(byte a0, short a1, char a2, int a3, long a4);
aoqi@0 164 }
aoqi@0 165
aoqi@0 166 interface Box {
aoqi@0 167 public String m(byte a0, short a1, char a2, int a3, long a4, boolean a5, float a6, double a7);
aoqi@0 168 }
aoqi@0 169
aoqi@0 170 static String pb(Byte a0, Short a1, Character a2, Integer a3, Long a4, Boolean a5, Float a6, Double a7) {
aoqi@0 171 return String.format("b%d s%d c%c i%d j%d z%b f%f d%f", a0, a1, a2, a3, a4, a5, a6, a7);
aoqi@0 172 }
aoqi@0 173
aoqi@0 174 static String pwI1(int a0, int a1, int a2, int a3) {
aoqi@0 175 return String.format("b%d s%d c%d i%d", a0, a1, a2, a3);
aoqi@0 176 }
aoqi@0 177
aoqi@0 178 static String pwI2(Integer a0, Integer a1, Integer a2, Integer a3) {
aoqi@0 179 return String.format("b%d s%d c%d i%d", a0, a1, a2, a3);
aoqi@0 180 }
aoqi@0 181
aoqi@0 182 static String pwL1(long a0, long a1, long a2, long a3, long a4) {
aoqi@0 183 return String.format("b%d s%d c%d i%d j%d", a0, a1, a2, a3, a4);
aoqi@0 184 }
aoqi@0 185
aoqi@0 186 static String pwL2(Long a0, Long a1, Long a2, Long a3, Long a4) {
aoqi@0 187 return String.format("b%d s%d c%d i%d j%d", a0, a1, a2, a3, a4);
aoqi@0 188 }
aoqi@0 189
aoqi@0 190 static String pwS1(short a0, short a1) {
aoqi@0 191 return String.format("b%d s%d", a0, a1);
aoqi@0 192 }
aoqi@0 193
aoqi@0 194 static String pwS2(Short a0, Short a1) {
aoqi@0 195 return String.format("b%d s%d", a0, a1);
aoqi@0 196 }
aoqi@0 197
aoqi@0 198 static String pwD1(double a0, double a1) {
aoqi@0 199 return String.format("f%f d%f", a0, a1);
aoqi@0 200 }
aoqi@0 201
aoqi@0 202 static String pwD2(Double a0, Double a1) {
aoqi@0 203 return String.format("f%f d%f", a0, a1);
aoqi@0 204 }
aoqi@0 205
aoqi@0 206 public void testPrimitiveWidening() {
aoqi@0 207 WidenS ws1 = LambdaTranslationTest2::pwS1;
aoqi@0 208 assertEquals("b1 s2", ws1.m((byte) 1, (short) 2));
aoqi@0 209
aoqi@0 210 WidenD wd1 = LambdaTranslationTest2::pwD1;
aoqi@0 211 assertEquals("f1.000000 d2.000000", wd1.m(1.0f, 2.0));
aoqi@0 212
aoqi@0 213 WidenI wi1 = LambdaTranslationTest2::pwI1;
aoqi@0 214 assertEquals("b1 s2 c3 i4", wi1.m((byte) 1, (short) 2, (char) 3, 4));
aoqi@0 215
aoqi@0 216 WidenL wl1 = LambdaTranslationTest2::pwL1;
aoqi@0 217 assertEquals("b1 s2 c3 i4 j5", wl1.m((byte) 1, (short) 2, (char) 3, 4, 5L));
aoqi@0 218
aoqi@0 219 // @@@ TODO: clarify spec on widen+box conversion
aoqi@0 220 }
aoqi@0 221
aoqi@0 222 interface Unbox {
aoqi@0 223 public String m(Byte a0, Short a1, Character a2, Integer a3, Long a4, Boolean a5, Float a6, Double a7);
aoqi@0 224 }
aoqi@0 225
aoqi@0 226 static String pu(byte a0, short a1, char a2, int a3, long a4, boolean a5, float a6, double a7) {
aoqi@0 227 return String.format("b%d s%d c%c i%d j%d z%b f%f d%f", a0, a1, a2, a3, a4, a5, a6, a7);
aoqi@0 228 }
aoqi@0 229
aoqi@0 230 public void testUnboxing() {
aoqi@0 231 Unbox u = LambdaTranslationTest2::pu;
aoqi@0 232 assertEquals("b1 s2 cA i4 j5 ztrue f6.000000 d7.000000", u.m((byte)1, (short) 2, 'A', 4, 5L, true, 6.0f, 7.0));
aoqi@0 233 }
aoqi@0 234
aoqi@0 235 public void testBoxing() {
aoqi@0 236 Box b = LambdaTranslationTest2::pb;
aoqi@0 237 assertEquals("b1 s2 cA i4 j5 ztrue f6.000000 d7.000000", b.m((byte) 1, (short) 2, 'A', 4, 5L, true, 6.0f, 7.0));
aoqi@0 238 }
aoqi@0 239
aoqi@0 240 static boolean cc(Object o) {
aoqi@0 241 return ((String) o).equals("foo");
aoqi@0 242 }
aoqi@0 243
aoqi@0 244 public void testArgCastingAdaptation() {
aoqi@0 245 TPredicate<String> p = LambdaTranslationTest2::cc;
aoqi@0 246 assertTrue(p.test("foo"));
aoqi@0 247 assertTrue(!p.test("bar"));
aoqi@0 248 }
aoqi@0 249
aoqi@0 250 interface SonOfPredicate<T> extends TPredicate<T> { }
aoqi@0 251
aoqi@0 252 public void testExtendsSAM() {
aoqi@0 253 SonOfPredicate<String> p = s -> s.isEmpty();
aoqi@0 254 assertTrue(p.test(""));
aoqi@0 255 assertTrue(!p.test("foo"));
aoqi@0 256 }
aoqi@0 257
aoqi@0 258 public void testConstructorRef() {
aoqi@0 259 Factory<List<String>> lf = ArrayList<String>::new;
aoqi@0 260 List<String> list = lf.make();
aoqi@0 261 assertTrue(list instanceof ArrayList);
aoqi@0 262 assertTrue(list != lf.make());
aoqi@0 263 list.add("a");
aoqi@0 264 assertEquals("[a]", list.toString());
aoqi@0 265 }
aoqi@0 266
aoqi@0 267 private static String privateMethod() {
aoqi@0 268 return "private";
aoqi@0 269 }
aoqi@0 270
aoqi@0 271 public void testPrivateMethodRef() {
aoqi@0 272 Factory<String> sf = LambdaTranslationTest2::privateMethod;
aoqi@0 273 assertEquals("private", sf.make());
aoqi@0 274 }
aoqi@0 275
aoqi@0 276 private interface PrivateIntf {
aoqi@0 277 String make();
aoqi@0 278 }
aoqi@0 279
aoqi@0 280 public void testPrivateIntf() {
aoqi@0 281 PrivateIntf p = () -> "foo";
aoqi@0 282 assertEquals("foo", p.make());
aoqi@0 283 }
aoqi@0 284
aoqi@0 285 interface Op<T> {
aoqi@0 286 public T op(T a, T b);
aoqi@0 287 }
aoqi@0 288
aoqi@0 289 public void testBoxToObject() {
aoqi@0 290 Op<Integer> maxer = Math::max;
aoqi@0 291 for (int i=-100000; i < 100000; i += 100)
aoqi@0 292 for (int j=-100000; j < 100000; j += 99) {
aoqi@0 293 assertEquals((int) maxer.op(i,j), Math.max(i,j));
aoqi@0 294 }
aoqi@0 295 }
aoqi@0 296
aoqi@0 297 protected static String protectedMethod() {
aoqi@0 298 return "protected";
aoqi@0 299 }
aoqi@0 300
aoqi@0 301 public void testProtectedMethodRef() {
aoqi@0 302 Factory<String> sf = LambdaTranslationTest2::protectedMethod;
aoqi@0 303 assertEquals("protected", sf.make());
aoqi@0 304 }
aoqi@0 305
aoqi@0 306 class Inner1 {
aoqi@0 307 String m1() {
aoqi@0 308 return "Inner1.m1()";
aoqi@0 309 }
aoqi@0 310
aoqi@0 311 class Inner2 {
aoqi@0 312 public String m1() {
aoqi@0 313 return "Inner1.Inner2.m1()";
aoqi@0 314 }
aoqi@0 315
aoqi@0 316 protected String m2() {
aoqi@0 317 return "Inner1.Inner2.m2()";
aoqi@0 318 }
aoqi@0 319
aoqi@0 320 String m3() {
aoqi@0 321 return "Inner1.Inner2.m3()";
aoqi@0 322 }
aoqi@0 323
aoqi@0 324 class Inner3<T> {
aoqi@0 325 T t = null;
aoqi@0 326 Inner3(T t) {
aoqi@0 327 this.t = t;
aoqi@0 328 }
aoqi@0 329 T m1() {
aoqi@0 330 return t;
aoqi@0 331 }
aoqi@0 332 }
aoqi@0 333 }
aoqi@0 334 }
aoqi@0 335
aoqi@0 336 public void testInnerClassMethodRef() {
aoqi@0 337 Factory<String> fs = new Inner1()::m1;
aoqi@0 338 assertEquals("Inner1.m1()", fs.make());
aoqi@0 339
aoqi@0 340 fs = new Inner1().new Inner2()::m1;
aoqi@0 341 assertEquals("Inner1.Inner2.m1()", fs.make());
aoqi@0 342
aoqi@0 343 fs = new Inner1().new Inner2()::m2;
aoqi@0 344 assertEquals("Inner1.Inner2.m2()", fs.make());
aoqi@0 345
aoqi@0 346 fs = new Inner1().new Inner2()::m3;
aoqi@0 347 assertEquals("Inner1.Inner2.m3()", fs.make());
aoqi@0 348
aoqi@0 349 fs = new Inner1().new Inner2().new Inner3<String>("Inner1.Inner2.Inner3")::m1;
aoqi@0 350 assertEquals("Inner1.Inner2.Inner3", fs.make());
aoqi@0 351
aoqi@0 352 Factory<Integer> fsi = new Inner1().new Inner2().new Inner3<Integer>(100)::m1;
aoqi@0 353 assertEquals(100, (int)fsi.make());
aoqi@0 354 }
aoqi@0 355 }

mercurial