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    /**
036     * A scanning visitor of program elements with default behavior
037     * appropriate for the {@link SourceVersion#RELEASE_6 RELEASE_6}
038     * source version.  The <tt>visit<i>XYZ</i></tt> methods in this
039     * class scan their component elements by calling {@code scan} on
040     * their {@linkplain Element#getEnclosedElements enclosed elements},
041     * {@linkplain ExecutableElement#getParameters parameters}, etc., as
042     * indicated in the individual method specifications.  A subclass can
043     * control the order elements are visited by overriding the
044     * <tt>visit<i>XYZ</i></tt> methods.  Note that clients of a scanner
045     * may get the desired behavior be invoking {@code v.scan(e, p)} rather
046     * than {@code v.visit(e, p)} on the root objects of interest.
047     *
048     * <p>When a subclass overrides a <tt>visit<i>XYZ</i></tt> method, the
049     * new method can cause the enclosed elements to be scanned in the
050     * default way by calling <tt>super.visit<i>XYZ</i></tt>.  In this
051     * fashion, the concrete visitor can control the ordering of traversal
052     * over the component elements with respect to the additional
053     * processing; for example, consistently calling
054     * <tt>super.visit<i>XYZ</i></tt> at the start of the overridden
055     * methods will yield a preorder traversal, etc.  If the component
056     * elements should be traversed in some other order, instead of
057     * calling <tt>super.visit<i>XYZ</i></tt>, an overriding visit method
058     * should call {@code scan} with the elements in the desired order.
059     *
060     * <p> Methods in this class may be overridden subject to their
061     * general contract.  Note that annotating methods in concrete
062     * subclasses with {@link java.lang.Override @Override} will help
063     * ensure that methods are overridden as intended.
064     *
065     * <p> <b>WARNING:</b> The {@code ElementVisitor} interface
066     * implemented by this class may have methods added to it in the
067     * future to accommodate new, currently unknown, language structures
068     * added to future versions of the Java&trade; programming language.
069     * Therefore, methods whose names begin with {@code "visit"} may be
070     * added to this class in the future; to avoid incompatibilities,
071     * classes which extend this class should not declare any instance
072     * methods with names beginning with {@code "visit"}.
073     *
074     * <p>When such a new visit method is added, the default
075     * implementation in this class will be to call the {@link
076     * #visitUnknown visitUnknown} method.  A new element scanner visitor
077     * class will also be introduced to correspond to the new language
078     * level; this visitor will have different default behavior for the
079     * visit method in question.  When the new visitor is introduced, all
080     * or portions of this visitor may be deprecated.
081     *
082     * @param <R> the return type of this visitor's methods.  Use {@link
083     *            Void} for visitors that do not need to return results.
084     * @param <P> the type of the additional parameter to this visitor's
085     *            methods.  Use {@code Void} for visitors that do not need an
086     *            additional parameter.
087     *
088     * @author Joseph D. Darcy
089     * @author Scott Seligman
090     * @author Peter von der Ah&eacute;
091     * @since 1.6
092     */
093    @SupportedSourceVersion(RELEASE_6)
094    public class ElementScanner6<R, P> extends AbstractElementVisitor6<R, P> {
095        /**
096         * The specified default value.
097         */
098        protected final R DEFAULT_VALUE;
099    
100        /**
101         * Constructor for concrete subclasses; uses {@code null} for the
102         * default value.
103         */
104        protected ElementScanner6(){
105            DEFAULT_VALUE = null;
106        }
107    
108        /**
109         * Constructor for concrete subclasses; uses the argument for the
110         * default value.
111         */
112        protected ElementScanner6(R defaultValue){
113            DEFAULT_VALUE = defaultValue;
114        }
115    
116        /**
117         * Iterates over the given elements and calls {@link
118         * #scan(Element, Object) scan(Element, P)} on each one.  Returns
119         * the result of the last call to {@code scan} or {@code
120         * DEFAULT_VALUE} for an empty iterable.
121         *
122         * @param iterable the elements to scan
123         * @param  p additional parameter
124         * @return the scan of the last element or {@code DEFAULT_VALUE} if no elements
125         */
126        public final R scan(Iterable<? extends Element> iterable, P p) {
127            R result = DEFAULT_VALUE;
128            for(Element e : iterable)
129                result = scan(e, p);
130            return result;
131        }
132    
133        /**
134         * Processes an element by calling {@code e.accept(this, p)};
135         * this method may be overridden by subclasses.
136         * @return the result of visiting {@code e}.
137         */
138        public R scan(Element e, P p) {
139            return e.accept(this, p);
140        }
141    
142        /**
143         * Convenience method equivalent to {@code v.scan(e, null)}.
144         * @return the result of scanning {@code e}.
145         */
146        public final R scan(Element e) {
147            return scan(e, null);
148        }
149    
150        /**
151         * {@inheritDoc} This implementation scans the enclosed elements.
152         *
153         * @param e  the element to visit
154         * @param p  a visitor-specified parameter
155         * @return the result of scanning
156         */
157        public R visitPackage(PackageElement e, P p) {
158            return scan(e.getEnclosedElements(), p);
159        }
160    
161        /**
162         * {@inheritDoc} This implementation scans the enclosed elements.
163         *
164         * @param e  the element to visit
165         * @param p  a visitor-specified parameter
166         * @return the result of scanning
167         */
168        public R visitType(TypeElement e, P p) {
169            return scan(e.getEnclosedElements(), p);
170        }
171    
172        /**
173         * {@inheritDoc} This implementation scans the enclosed elements.
174         *
175         * @param e  the element to visit
176         * @param p  a visitor-specified parameter
177         * @return the result of scanning
178         */
179        public R visitVariable(VariableElement e, P p) {
180            return scan(e.getEnclosedElements(), p);
181        }
182    
183        /**
184         * {@inheritDoc} This implementation scans the parameters.
185         *
186         * @param e  the element to visit
187         * @param p  a visitor-specified parameter
188         * @return the result of scanning
189         */
190        public R visitExecutable(ExecutableElement e, P p) {
191            return scan(e.getParameters(), p);
192        }
193    
194        /**
195         * {@inheritDoc} This implementation scans the enclosed elements.
196         *
197         * @param e  the element to visit
198         * @param p  a visitor-specified parameter
199         * @return the result of scanning
200         */
201        public R visitTypeParameter(TypeParameterElement e, P p) {
202            return scan(e.getEnclosedElements(), p);
203        }
204    }