001: /*
002: * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package javax.lang.model.util;
027:
028: import javax.lang.model.element.*;
029: import javax.annotation.processing.SupportedSourceVersion;
030: import static javax.lang.model.element.ElementKind.*;
031: import javax.lang.model.SourceVersion;
032: import static javax.lang.model.SourceVersion.*;
033:
034: /**
035: * A scanning visitor of program elements with default behavior
036: * appropriate for the {@link SourceVersion#RELEASE_6 RELEASE_6}
037: * source version. The <tt>visit<i>XYZ</i></tt> methods in this
038: * class scan their component elements by calling {@code scan} on
039: * their {@linkplain Element#getEnclosedElements enclosed elements},
040: * {@linkplain ExecutableElement#getParameters parameters}, etc., as
041: * indicated in the individual method specifications. A subclass can
042: * control the order elements are visited by overriding the
043: * <tt>visit<i>XYZ</i></tt> methods. Note that clients of a scanner
044: * may get the desired behavior be invoking {@code v.scan(e, p)} rather
045: * than {@code v.visit(e, p)} on the root objects of interest.
046: *
047: * <p>When a subclass overrides a <tt>visit<i>XYZ</i></tt> method, the
048: * new method can cause the enclosed elements to be scanned in the
049: * default way by calling <tt>super.visit<i>XYZ</i></tt>. In this
050: * fashion, the concrete visitor can control the ordering of traversal
051: * over the component elements with respect to the additional
052: * processing; for example, consistently calling
053: * <tt>super.visit<i>XYZ</i></tt> at the start of the overridden
054: * methods will yield a preorder traversal, etc. If the component
055: * elements should be traversed in some other order, instead of
056: * calling <tt>super.visit<i>XYZ</i></tt>, an overriding visit method
057: * should call {@code scan} with the elements in the desired order.
058: *
059: * <p> Methods in this class may be overridden subject to their
060: * general contract. Note that annotating methods in concrete
061: * subclasses with {@link java.lang.Override @Override} will help
062: * ensure that methods are overridden as intended.
063: *
064: * <p> <b>WARNING:</b> The {@code ElementVisitor} interface
065: * implemented by this class may have methods added to it in the
066: * future to accommodate new, currently unknown, language structures
067: * added to future versions of the Java™ programming language.
068: * Therefore, methods whose names begin with {@code "visit"} may be
069: * added to this class in the future; to avoid incompatibilities,
070: * classes which extend this class should not declare any instance
071: * methods with names beginning with {@code "visit"}.
072: *
073: * <p>When such a new visit method is added, the default
074: * implementation in this class will be to call the {@link
075: * #visitUnknown visitUnknown} method. A new element scanner visitor
076: * class will also be introduced to correspond to the new language
077: * level; this visitor will have different default behavior for the
078: * visit method in question. When the new visitor is introduced, all
079: * or portions of this visitor may be deprecated.
080: *
081: * @param <R> the return type of this visitor's methods. Use {@link
082: * Void} for visitors that do not need to return results.
083: * @param <P> the type of the additional parameter to this visitor's
084: * methods. Use {@code Void} for visitors that do not need an
085: * additional parameter.
086: *
087: * @author Joseph D. Darcy
088: * @author Scott Seligman
089: * @author Peter von der Ahé
090: * @version 1.13 07/05/05
091: * @since 1.6
092: */
093: @SupportedSourceVersion(RELEASE_6)
094: public class ElementScanner6<R, P> extends
095: AbstractElementVisitor6<R, P> {
096: /**
097: * The specified default value.
098: */
099: protected final R DEFAULT_VALUE;
100:
101: /**
102: * Constructor for concrete subclasses; uses {@code null} for the
103: * default value.
104: */
105: protected ElementScanner6() {
106: DEFAULT_VALUE = null;
107: }
108:
109: /**
110: * Constructor for concrete subclasses; uses the argument for the
111: * default value.
112: */
113: protected ElementScanner6(R defaultValue) {
114: DEFAULT_VALUE = defaultValue;
115: }
116:
117: /**
118: * Iterates over the given elements and calls {@link
119: * #scan(Element, Object) scan(Element, P)} on each one. Returns
120: * the result of the last call to {@code scan} or {@code
121: * DEFAULT_VALUE} for an empty iterable.
122: *
123: * @param iterable the elements to scan
124: * @param p additional parameter
125: * @return the scan of the last element or {@code DEFAULT_VALUE} if no elements
126: */
127: public final R scan(Iterable<? extends Element> iterable, P p) {
128: R result = DEFAULT_VALUE;
129: for (Element e : iterable)
130: result = scan(e, p);
131: return result;
132: }
133:
134: /**
135: * Processes an element by calling {@code e.accept(this, p)};
136: * this method may be overridden by subclasses.
137: * @return the result of visiting {@code e}.
138: */
139: public R scan(Element e, P p) {
140: return e.accept(this , p);
141: }
142:
143: /**
144: * Convenience method equivalent to {@code v.scan(e, null)}.
145: * @return the result of scanning {@code e}.
146: */
147: public final R scan(Element e) {
148: return scan(e, null);
149: }
150:
151: /**
152: * {@inheritDoc} This implementation scans the enclosed elements.
153: *
154: * @param e the element to visit
155: * @param p a visitor-specified parameter
156: * @return the result of scanning
157: */
158: public R visitPackage(PackageElement e, P p) {
159: return scan(e.getEnclosedElements(), p);
160: }
161:
162: /**
163: * {@inheritDoc} This implementation scans the enclosed elements.
164: *
165: * @param e the element to visit
166: * @param p a visitor-specified parameter
167: * @return the result of scanning
168: */
169: public R visitType(TypeElement e, P p) {
170: return scan(e.getEnclosedElements(), p);
171: }
172:
173: /**
174: * {@inheritDoc} This implementation scans the enclosed elements.
175: *
176: * @param e the element to visit
177: * @param p a visitor-specified parameter
178: * @return the result of scanning
179: */
180: public R visitVariable(VariableElement e, P p) {
181: return scan(e.getEnclosedElements(), p);
182: }
183:
184: /**
185: * {@inheritDoc} This implementation scans the parameters.
186: *
187: * @param e the element to visit
188: * @param p a visitor-specified parameter
189: * @return the result of scanning
190: */
191: public R visitExecutable(ExecutableElement e, P p) {
192: return scan(e.getParameters(), p);
193: }
194:
195: /**
196: * {@inheritDoc} This implementation scans the enclosed elements.
197: *
198: * @param e the element to visit
199: * @param p a visitor-specified parameter
200: * @return the result of scanning
201: */
202: public R visitTypeParameter(TypeParameterElement e, P p) {
203: return scan(e.getEnclosedElements(), p);
204: }
205: }
|