changeset 52954:7d26530a0558 datum

Fix ofConstant extractor factory
author briangoetz
date Thu, 01 Nov 2018 12:33:51 -0400
parents ad3177db8f2c
children 7d56987f69c2 421704de8d79
files src/java.base/share/classes/java/lang/compiler/Extractor.java test/jdk/java/lang/compiler/ExtractorTest.java test/jdk/java/lang/compiler/RecordTest.java
diffstat 3 files changed, 45 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/compiler/Extractor.java	Wed Oct 31 20:12:26 2018 -0400
+++ b/src/java.base/share/classes/java/lang/compiler/Extractor.java	Thu Nov 01 12:33:51 2018 -0400
@@ -29,6 +29,7 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
+import java.util.Arrays;
 import java.util.Objects;
 import java.util.stream.IntStream;
 import java.util.stream.Stream;
@@ -259,9 +260,11 @@
      * @return the extractor
      */
     public static Extractor ofConstant(Object o) {
-        MethodHandle match = partialize(MethodHandles.dropArguments(MethodHandles.constant(Object.class, Boolean.TRUE), 0, Object.class),
-                                        MethodHandles.insertArguments(ExtractorImpl.MH_OBJECTS_EQUAL, 0, o));
-        return new ExtractorImpl(MethodType.methodType(Object.class), match);
+        Class<?> type = o == null ? Object.class : o.getClass();
+        MethodHandle match = partialize(MethodHandles.dropArguments(MethodHandles.constant(Object.class, Boolean.TRUE), 0, type),
+                                        MethodHandles.insertArguments(ExtractorImpl.MH_OBJECTS_EQUAL, 0, o)
+                                                     .asType(MethodType.methodType(boolean.class, type)));
+        return new ExtractorImpl(MethodType.methodType(type), match);
     }
 
     /**
--- a/test/jdk/java/lang/compiler/ExtractorTest.java	Wed Oct 31 20:12:26 2018 -0400
+++ b/test/jdk/java/lang/compiler/ExtractorTest.java	Thu Nov 01 12:33:51 2018 -0400
@@ -48,9 +48,9 @@
 @Test
 public class ExtractorTest {
 
-    private enum MatchKind { CARRIER, SELF, FAIL, MATCH }
+    enum MatchKind { CARRIER, SELF, FAIL, MATCH }
 
-    private void assertMatch(MatchKind kind, Extractor e, Object target, Object... args) throws Throwable {
+    static void assertMatch(MatchKind kind, Extractor e, Object target, Object... args) throws Throwable {
         int count = e.descriptor().parameterCount();
         Object[] bindings = new Object[count];
         Object carrier = Extractor.adapt(e, Object.class).tryMatch().invoke(target);
@@ -256,6 +256,7 @@
         assertMatch(MatchKind.FAIL, Extractor.ofConstant("foo"), "bar");
         assertMatch(MatchKind.FAIL, Extractor.ofConstant("foo"), 3);
         assertMatch(MatchKind.FAIL, Extractor.ofConstant("foo"), null);
+        assertMatch(MatchKind.MATCH, Extractor.ofConstant(3), 3);
     }
 
     public void testNested() throws Throwable {
@@ -272,6 +273,5 @@
 
         assertMatch(MatchKind.CARRIER, Extractor.dropBindings(Extractor.ofNested(TC2, Extractor.ofNested(TC2, STRING)), 0, 1), new TestClass2(new TestClass2("foo")),
                     "foo");
-
     }
 }
--- a/test/jdk/java/lang/compiler/RecordTest.java	Wed Oct 31 20:12:26 2018 -0400
+++ b/test/jdk/java/lang/compiler/RecordTest.java	Thu Nov 01 12:33:51 2018 -0400
@@ -207,6 +207,42 @@
         assertEquals(((SwitchBootstraps.PatternSwitchResult) mh.invoke(new Box(null))).index, 2);
         assertEquals(((SwitchBootstraps.PatternSwitchResult) mh.invoke("foo")).index, 2);
         assertEquals(((SwitchBootstraps.PatternSwitchResult) mh.invoke(null)).index, -1);
+    }
 
+    record RString(String i) { }
+    record RObject(Object i) { }
+    record Rint(int i) { }
+
+
+    public void testNestedWithConstant() throws Throwable {
+        Extractor rb = recordExtractor(Box.class, Object.class);
+        Extractor rs = recordExtractor(RString.class, String.class);
+        Extractor ro = recordExtractor(RObject.class, Object.class);
+        Extractor ri = recordExtractor(Rint.class, int.class);
+        Extractor cs = Extractor.ofConstant("foo");
+        Extractor cn = Extractor.ofConstant(null);
+        Extractor ci = Extractor.ofConstant(3);
+
+        ExtractorTest.assertMatch(ExtractorTest.MatchKind.MATCH, Extractor.ofNested(rs, cs), new RString("foo"), "foo");
+        ExtractorTest.assertMatch(ExtractorTest.MatchKind.FAIL, Extractor.ofNested(rs, cs), new RString("bar"));
+        ExtractorTest.assertMatch(ExtractorTest.MatchKind.FAIL, Extractor.ofNested(rs, cs), new RString(null));
+
+        ExtractorTest.assertMatch(ExtractorTest.MatchKind.MATCH, Extractor.ofNested(ro, cs), new RObject("foo"), "foo");
+        ExtractorTest.assertMatch(ExtractorTest.MatchKind.FAIL, Extractor.ofNested(ro, cs), new RObject("bar"));
+        ExtractorTest.assertMatch(ExtractorTest.MatchKind.FAIL, Extractor.ofNested(ro, cs), new RObject(3));
+        ExtractorTest.assertMatch(ExtractorTest.MatchKind.FAIL, Extractor.ofNested(ro, cs), new RObject(null));
+
+        ExtractorTest.assertMatch(ExtractorTest.MatchKind.MATCH, Extractor.ofNested(ri, ci), new Rint(3), 3);
+        ExtractorTest.assertMatch(ExtractorTest.MatchKind.FAIL, Extractor.ofNested(ri, ci), new Rint(2));
+
+        ExtractorTest.assertMatch(ExtractorTest.MatchKind.MATCH,
+                                  Extractor.ofNested(rb, Extractor.ofNested(rs, cs)),
+                                  new Box(new RString("foo")), new RString("foo"), "foo");
+        ExtractorTest.assertMatch(ExtractorTest.MatchKind.FAIL,
+                                  Extractor.ofNested(rb, Extractor.ofNested(rs, cs)),
+                                  new Box(new RString("bar")));
+        ExtractorTest.assertMatch(ExtractorTest.MatchKind.FAIL,
+                                  Extractor.ofNested(rb, Extractor.ofNested(rs, cs)),
+                                  new Box("foo"));
     }
 }