1 /*
2 * Copyright (c) 2024, 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
26 package jdk.incubator.code;
27
28 import java.lang.annotation.*;
29 import java.lang.reflect.Method;
30
31 /**
32 * An annotation that is used to declare reflectable methods, lambda expressions, and method references. Declaration
33 * of such reflectable program elements enables access to their code as a code model.
34 * <p>
35 * The code model of a reflectable method is accessed by invoking {@link Op#ofMethod(Method)} with an argument
36 * that is a {@link Method} instance (retrieved using core reflection) representing the reflectable method. The result
37 * is an optional value that contains a root operation modeling the method.
38 * <p>
39 * The code model of a reflectable lambda expression (or method reference) is accessed by invoking
40 * {@link Op#ofLambda(Object)} with an argument that is an instance of a functional interface associated with the
41 * reflectable lambda expression. The result is an optional value that contains a {@link Quoted quoted} instance, from
42 * which may be retrieved the operation modelling the lambda expression. In addition, it is possible to retrieve a
43 * mapping of run time values to items in the code model that model final, or effectively final, variables used but not
44 * declared in the lambda expression.
45 * <p>
46 * There are four syntactic locations where {@code @Reflect} can appear that governs, in increasing scope, what is
47 * declared reflectable.
48 * <ul>
49 * <li>
50 * If the annotation appears in a cast expression of a lambda expression (or method reference), annotating the use of
51 * the type in the cast operator of the cast expression, then the lambda expression is declared reflectable.
52 * </li>
53 * <li>
54 * If the annotation appears as a modifier for a field declaration or a local variable declaration, annotating the
55 * field or local variable, then any lambda expressions (or method references) in the variable initializer expression
56 * (if present) are declared reflectable. This is useful when cast expressions become verbose and/or types become hard
57 * to reason about. For example, with fluent stream-like expressions where many reflectable lambda expressions are
58 * passed as arguments.
59 * </li>
60 * <li>
61 * Finally, if the annotation appears as a modifier for a non-abstract method declaration, annotating the method, then
62 * the method and any lambda expressions (or method references) it contains are declared reflectable.
63 * </li>
64 * </ul>
65 * The annotation is ignored if it appears in any other valid syntactic location.
66 * <p>
67 * Declaring a reflectable lambda expression or method does not implicitly broaden the scope of what is reflectable to
68 * methods they invoke. Furthermore, declaring a reflectable lambda expression does broaden the scope to the surrounding
69 * code of final, or effectively final, variables used but not declared in the lambda expression.
70 * Declaring a reflectable method reference does not implicitly broaden the scope to the referenced method.
71 * A reflectable method reference's code model is the same as the code model of an equivalent reflectable lambda
72 * expression whose body invokes the referenced method.
73 */
74 @Target({ElementType.LOCAL_VARIABLE, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE_USE})
75 @Retention(RetentionPolicy.RUNTIME)
76 public @interface Reflect {
77 }