1 /*
   2  * Copyright (c) 2019, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.lang.runtime;
  26 
  27 import java.lang.invoke.MethodHandle;
  28 import java.lang.invoke.MethodType;
  29 import java.util.List;
  30 
  31 /**
  32  * Runtime object for low-level implementation of <em>pattern matching</em>. A
  33  * {@linkplain PatternHandle} exposes functionality for determining if a target
  34  * matches the pattern, and if so, for conditionally extracting the resulting
  35  * bindings.
  36  *
  37  * <p>A {@linkplain PatternHandle} is parameterized by a <em>target type</em>
  38  * and zero or more <em>binding variable types</em>. The target type (denoted
  39  * {@code T}) is the type against which the pattern can be applied (often a
  40  * broad type such as {@link Object}, but need not be), and the binding variable
  41  * types (denoted {@code B*}) are the types of the binding variables that are
  42  * produced by a successful match.  These types are combined into a type
  43  * <em>descriptor</em>, accessed via {@link #descriptor()}, where the return
  44  * type of the descriptor is the target type, and the parameter types of the
  45  * descriptor are the binding variable types.
  46  *
  47  * <p>The behavior of a {@linkplain PatternHandle} is exposed via method
  48  * handles.  The method handle returned by {@link #tryMatch()} is applied to the
  49  * target to be tested, and returns an opaque result of type {@code Object}.  If
  50  * the result is {@code null}, the match has failed; if is non-null, it has
  51  * succeeded, and the result can be used as input to the method handles returned
  52  * by {@link #components()} or {@link #component(int)} to retrieve specific
  53  * binding variables.
  54  *
  55  * <p>The class {@link PatternHandles} contains numerous factories and
  56  * combinators for {@linkplain PatternHandle}s, including {@link
  57  * PatternHandles#adaptTarget(PatternHandle, Class)} which can be used to adapt
  58  * a pattern handle from one target type to another (such as widening the set of
  59  * types against which it can be applied.)
  60  *
  61  * <p>{@linkplain PatternHandle} implementations must be <a
  62  * href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
  63  * classes.
  64  */
  65 public interface PatternHandle {
  66 
  67     /**
  68      * Returns a method handle that attempts to perform the pattern match
  69      * described by this pattern handle.  It will have type {@code (T)Object},
  70      * where {@code T} is the target type of the extractor. It accepts the
  71      * target to be matched, and returns a non-null opaque carrier of type
  72      * {@link Object} if the match succeeds, or {@code null} if it fails.
  73      *
  74      * @return the {@code tryMatch} method handle
  75      */
  76     MethodHandle tryMatch();
  77 
  78     /**
  79      * Returns a method handle that extracts a component from a successful
  80      * match.  It will have type {@code (Object)Bi}, where {@code Bi} is the
  81      * type of the corresponding binding variable, and will take the match
  82      * carrier and return the corresponding binding variable.
  83      *
  84      * @param i the index of the component
  85      * @return the component method handle
  86      * @throws IndexOutOfBoundsException if {@code i} does not correspond to the
  87      *                                   index of a binding variable of this
  88      *                                   pattern
  89      */
  90     MethodHandle component(int i);
  91 
  92     /**
  93      * Returns all the component method handles for this pattern as a {@link
  94      * List}.
  95      *
  96      * @return the component method handles
  97      */
  98     List<MethodHandle> components();
  99 
 100     /**
 101      * Returns the descriptor for this pattern.  The parameter types of the
 102      * descriptor are the types of the binding variables, and the return type is
 103      * the target type.
 104      *
 105      * @return the pattern type descriptor
 106      */
 107     MethodType descriptor();
 108 }