1 /*
2  * Copyright (c) 2005, 2020, 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 javax.lang.model.element;
27 
28 import javax.lang.model.util.*;
29 
30 /**
31  * A visitor of program elements, in the style of the visitor design
32  * pattern.  Classes implementing this interface are used to operate
33  * on an element when the kind of element is unknown at compile time.
34  * When a visitor is passed to an element's {@link Element#accept
35  * accept} method, the <code>visit<i>Xyz</i></code> method most applicable
36  * to that element is invoked.
37  *
38  * <p> Classes implementing this interface may or may not throw a
39  * {@code NullPointerException} if the additional parameter {@code p}
40  * is {@code null}; see documentation of the implementing class for
41  * details.
42  *
43  * @apiNote
44  * <strong>WARNING:</strong> It is possible that methods will be added
45  * to this interface to accommodate new, currently unknown, language
46  * structures added to future versions of the Java programming
47  * language.
48  *
49  * Such additions have already occurred to support language features
50  * added after this API was introduced.
51  *
52  * Visitor classes directly implementing this interface may be source
53  * incompatible with future versions of the platform.  To avoid this
54  * source incompatibility, visitor implementations are encouraged to
55  * instead extend the appropriate abstract visitor class that
56  * implements this interface.  However, an API should generally use
57  * this visitor interface as the type for parameters, return type,
58  * etc. rather than one of the abstract classes.
59  *
60  * <p>Methods to accommodate new language constructs are expected to
61  * be added as default methods to provide strong source compatibility,
62  * as done for {@link visitModule visitModule}. The implementations of
63  * the default methods will in turn call {@link visitUnknown
64  * visitUnknown}, behavior that will be overridden in concrete
65  * visitors supporting the source version with the new language
66  * construct.
67  *
68  * <p>There are several families of classes implementing this visitor
69  * interface in the {@linkplain javax.lang.model.util util
70  * package}. The families follow a naming pattern along the lines of
71  * {@code FooVisitor}<i>N</i> where <i>N</i> indicates the
72  * {@linkplain javax.lang.model.SourceVersion source version} the
73  * visitor is appropriate for.
74  *
75  * In particular, a {@code FooVisitor}<i>N</i> is expected to handle
76  * all language constructs present in source version <i>N</i>. If
77  * there are no new language constructs added in version
78  * <i>N</i>&nbsp;+&nbsp;1 (or subsequent releases), {@code
79  * FooVisitor}<i>N</i> may also handle that later source version; in
80  * that case, the {@link
81  * javax.annotation.processing.SupportedSourceVersion
82  * SupportedSourceVersion} annotation on the {@code
83  * FooVisitor}<i>N</i> class will indicate a later version.
84  *
85  * When visiting an element representing a language construct
86  * introduced <strong>after</strong> source version <i>N</i>, a {@code
87  * FooVisitor}<i>N</i> will throw an {@link UnknownElementException}
88  * unless that behavior is overridden.
89  *
90  * <p>When choosing which member of a visitor family to subclass,
91  * subclassing the most recent one increases the range of source
92  * versions covered. When choosing which visitor family to subclass,
93  * consider their built-in capabilities:
94  *
95  * <ul>
96  *
97  * <li>{@link AbstractElementVisitor6 AbstractElementVisitor}s:
98  * Skeletal visitor implementations.
99  *
100  * <li>{@link SimpleElementVisitor6 SimpleElementVisitor}s: Support
101  * default actions and a default return value.
102  *
103  * <li>{@link ElementKindVisitor6 ElementKindVisitor}s: Visit methods
104  * provided on a {@linkplain Element#getKind per-kind} granularity as
105  * some categories of elements can have more than one kind.
106  *
107  * <li>{@link ElementScanner6 ElementScanner}s: Scanners are visitors
108  * which traverse an element and the elements {@linkplain
109  * Element#getEnclosedElements enclosed} by it and associated with it.
110  *
111  * </ul>
112  *
113  * @param <R> the return type of this visitor's methods.  Use {@link
114  *            Void} for visitors that do not need to return results.
115  * @param <P> the type of the additional parameter to this visitor's
116  *            methods.  Use {@code Void} for visitors that do not need an
117  *            additional parameter.
118  *
119  * @author Joseph D. Darcy
120  * @author Scott Seligman
121  * @author Peter von der Ah&eacute;
122  * @since 1.6
123  */
124 public interface ElementVisitor<R, P> {
125     /**
126      * Visits an element.
127      * @param e  the element to visit
128      * @param p  a visitor-specified parameter
129      * @return a visitor-specified result
130      */
visit(Element e, P p)131     R visit(Element e, P p);
132 
133     /**
134      * A convenience method equivalent to {@code visit(e, null)}.
135      *
136      * @implSpec The default implementation is {@code visit(e, null)}.
137      *
138      * @param e  the element to visit
139      * @return a visitor-specified result
140      */
visit(Element e)141     default R visit(Element e) {
142         return visit(e, null);
143     }
144 
145     /**
146      * Visits a package element.
147      * @param e  the element to visit
148      * @param p  a visitor-specified parameter
149      * @return a visitor-specified result
150      */
visitPackage(PackageElement e, P p)151     R visitPackage(PackageElement e, P p);
152 
153     /**
154      * Visits a type element.
155      * @param e  the element to visit
156      * @param p  a visitor-specified parameter
157      * @return a visitor-specified result
158      */
visitType(TypeElement e, P p)159     R visitType(TypeElement e, P p);
160 
161     /**
162      * Visits a variable element.
163      * @param e  the element to visit
164      * @param p  a visitor-specified parameter
165      * @return a visitor-specified result
166      */
visitVariable(VariableElement e, P p)167     R visitVariable(VariableElement e, P p);
168 
169     /**
170      * Visits an executable element.
171      * @param e  the element to visit
172      * @param p  a visitor-specified parameter
173      * @return a visitor-specified result
174      */
visitExecutable(ExecutableElement e, P p)175     R visitExecutable(ExecutableElement e, P p);
176 
177     /**
178      * Visits a type parameter element.
179      * @param e  the element to visit
180      * @param p  a visitor-specified parameter
181      * @return a visitor-specified result
182      */
visitTypeParameter(TypeParameterElement e, P p)183     R visitTypeParameter(TypeParameterElement e, P p);
184 
185     /**
186      * Visits an unknown kind of element.
187      * This can occur if the language evolves and new kinds
188      * of elements are added to the {@code Element} hierarchy.
189      *
190      * @param e  the element to visit
191      * @param p  a visitor-specified parameter
192      * @return a visitor-specified result
193      * @throws UnknownElementException
194      *  a visitor implementation may optionally throw this exception
195      */
visitUnknown(Element e, P p)196     R visitUnknown(Element e, P p);
197 
198     /**
199      * Visits a module element.
200      *
201      * @implSpec The default implementation visits a {@code
202      * ModuleElement} by calling {@code visitUnknown(e, p)}.
203      *
204      * @param e  the element to visit
205      * @param p  a visitor-specified parameter
206      * @return a visitor-specified result
207      * @since 9
208      */
visitModule(ModuleElement e, P p)209     default R visitModule(ModuleElement e, P p) {
210         return visitUnknown(e, p);
211     }
212 
213     /**
214      * Visits a record component element.
215      *
216      * @implSpec The default implementation visits a {@code
217      * RecordComponentElement} by calling {@code visitUnknown(e, p)}.
218      *
219      * @param e  the element to visit
220      * @param p  a visitor-specified parameter
221      * @return a visitor-specified result
222      * @since 16
223      */
visitRecordComponent(RecordComponentElement e, P p)224     default R visitRecordComponent(RecordComponentElement e, P p) {
225         return visitUnknown(e, p);
226     }
227 }
228