changeset 52949:9e4fc2e97fd0 datum

Add support for constant patterns
author briangoetz
date Wed, 31 Oct 2018 13:21:55 -0400
parents c9cfa7d5778d
children aa666a24f362 859f3cb2cd75
files src/java.base/share/classes/java/lang/compiler/Extractor.java src/java.base/share/classes/java/lang/compiler/ExtractorImpl.java test/jdk/java/lang/compiler/ExtractorTest.java
diffstat 3 files changed, 43 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/compiler/Extractor.java	Tue Oct 30 23:11:00 2018 -0400
+++ b/src/java.base/share/classes/java/lang/compiler/Extractor.java	Wed Oct 31 13:21:55 2018 -0400
@@ -253,6 +253,18 @@
     }
 
     /**
+     * Create an {@linkplain Extractor} for a constant pattern
+     *
+     * @param o the constant
+     * @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);
+    }
+
+    /**
      * Create an {@linkplain Extractor} for a nullable type pattern, with a
      * single binding variable, whose target type is {@code Object}
      *
@@ -424,12 +436,12 @@
      *
      * @param lookup ignored
      * @param invocationName ignored
-     * @param invocationType ignored
+     * @param invocationType must be {@code Class<Extractor>}
      * @param outer the outer extractor
      * @param inners the inner extractors, null if no nesting is needed for this binding
      * @return the nested extractor
      */
-    public static Extractor ofNested(MethodHandles.Lookup lookup, String invocationName, MethodType invocationType,
+    public static Extractor ofNested(MethodHandles.Lookup lookup, String invocationName, Class<Extractor> invocationType,
                                      Extractor outer, Extractor... inners) {
         return ofNested(outer, inners);
     }
@@ -439,11 +451,11 @@
      *
      * @param lookup ignored
      * @param invocationName ignored
-     * @param invocationType ignored
+     * @param invocationType must be {@code Class<Extractor>}
      * @param type the type
      * @return the extractor
      */
-    public static Extractor ofType(MethodHandles.Lookup lookup, String invocationName, MethodType invocationType,
+    public static Extractor ofType(MethodHandles.Lookup lookup, String invocationName, Class<Extractor> invocationType,
                                    Class<?> type) {
         return ofType(type);
     }
@@ -453,16 +465,30 @@
      *
      * @param lookup ignored
      * @param invocationName ignored
-     * @param invocationType ignored
+     * @param invocationType must be {@code Class<Extractor>}
      * @param type the type
      * @return the extractor
      */
-    public static Extractor ofTypeNullable(MethodHandles.Lookup lookup, String invocationName, MethodType invocationType,
+    public static Extractor ofTypeNullable(MethodHandles.Lookup lookup, String invocationName, Class<Extractor> invocationType,
                                            Class<?> type) {
         return ofTypeNullable(type);
     }
 
     /**
+     * Condy bootstrap for creating constant extractor
+     *
+     * @param lookup ignored
+     * @param invocationName ignored
+     * @param invocationType must be {@code Class<Extractor>}
+     * @param constant the constant
+     * @return the extractor
+     */
+    public static Extractor ofConstant(MethodHandles.Lookup lookup, String invocationName, Class<Extractor> invocationType,
+                                       Object constant) {
+        return ofConstant(constant);
+    }
+
+    /**
      * Condy bootstrap for finding extractors
      *
      * @param lookup the lookup context
--- a/src/java.base/share/classes/java/lang/compiler/ExtractorImpl.java	Tue Oct 30 23:11:00 2018 -0400
+++ b/src/java.base/share/classes/java/lang/compiler/ExtractorImpl.java	Wed Oct 31 13:21:55 2018 -0400
@@ -44,6 +44,7 @@
     static final MethodHandle MH_ADAPT_HELPER;
     static final MethodHandle MH_OBJECTS_ISNULL;
     static final MethodHandle MH_OBJECTS_NONNULL;
+    static final MethodHandle MH_OBJECTS_EQUAL;
     static {
         try {
             MH_OF_TYPE_HELPER = MethodHandles.lookup().findStatic(ExtractorImpl.class, "ofTypeHelper", MethodType.methodType(Object.class, Class.class, Object.class));
@@ -51,6 +52,7 @@
             MH_ADAPT_HELPER = MethodHandles.lookup().findStatic(ExtractorImpl.class, "adaptHelper", MethodType.methodType(boolean.class, Class.class, Object.class));
             MH_OBJECTS_ISNULL = MethodHandles.lookup().findStatic(Objects.class, "isNull", MethodType.methodType(boolean.class, Object.class));
             MH_OBJECTS_NONNULL = MethodHandles.lookup().findStatic(Objects.class, "nonNull", MethodType.methodType(boolean.class, Object.class));
+            MH_OBJECTS_EQUAL = MethodHandles.lookup().findStatic(Objects.class, "equals", MethodType.methodType(boolean.class, Object.class, Object.class));
         }
         catch (ReflectiveOperationException e) {
             throw new ExceptionInInitializerError(e);
--- a/test/jdk/java/lang/compiler/ExtractorTest.java	Tue Oct 30 23:11:00 2018 -0400
+++ b/test/jdk/java/lang/compiler/ExtractorTest.java	Wed Oct 31 13:21:55 2018 -0400
@@ -249,6 +249,15 @@
         assertMatch(MatchKind.MATCH, Extractor.ofTypeNullable(String.class), null, (Object) null);
     }
 
+    public void testConstant() throws Throwable {
+        assertMatch(MatchKind.MATCH, Extractor.ofConstant(null), null);
+        assertMatch(MatchKind.FAIL, Extractor.ofConstant(null), "foo");
+        assertMatch(MatchKind.MATCH, Extractor.ofConstant("foo"), "foo");
+        assertMatch(MatchKind.FAIL, Extractor.ofConstant("foo"), "bar");
+        assertMatch(MatchKind.FAIL, Extractor.ofConstant("foo"), 3);
+        assertMatch(MatchKind.FAIL, Extractor.ofConstant("foo"), null);
+    }
+
     public void testNested() throws Throwable {
         Extractor TC2 = Extractor.ofTotal(TestClass2.class, TestClass2.MH_X);
         Extractor STRING = Extractor.ofType(String.class);