Path: blob/master/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeScanner.java
41175 views
/*1* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.source.util;2627import com.sun.source.doctree.*;282930/**31* A DocTreeVisitor that visits all the child tree nodes.32* To visit nodes of a particular type, just override the33* corresponding visitXYZ method.34* Inside your method, call super.visitXYZ to visit descendant35* nodes.36*37* <p>The default implementation of the visitXYZ methods will determine38* a result as follows:39* <ul>40* <li>If the node being visited has no children, the result will be {@code null}.41* <li>If the node being visited has one child, the result will be the42* result of calling {@code scan} with that child. The child may be a simple node43* or itself a list of nodes.44* <li>If the node being visited has more than one child, the result will45* be determined by calling {@code scan} with each child in turn, and then combining the46* result of each scan after the first with the cumulative result47* so far, as determined by the {@link #reduce} method. Each child may be either48* a simple node or a list of nodes. The default behavior of the {@code reduce}49* method is such that the result of the visitXYZ method will be the result of50* the last child scanned.51* </ul>52*53* <p>Here is an example to count the number of erroneous nodes in a tree:54* <pre>55* class CountErrors extends DocTreeScanner<Integer,Void> {56* {@literal @}Override57* public Integer visitErroneous(ErroneousTree node, Void p) {58* return 1;59* }60* {@literal @}Override61* public Integer reduce(Integer r1, Integer r2) {62* return (r1 == null ? 0 : r1) + (r2 == null ? 0 : r2);63* }64* }65* </pre>66*67* @since 1.868*/69public class DocTreeScanner<R,P> implements DocTreeVisitor<R,P> {70/**71* Constructs a {@code DocTreeScanner}.72*/73public DocTreeScanner() {}7475/**76* Scans a single node.77* @param node the node to be scanned78* @param p a parameter value passed to the visit method79* @return the result value from the visit method80*/81public R scan(DocTree node, P p) {82return (node == null) ? null : node.accept(this, p);83}8485private R scanAndReduce(DocTree node, P p, R r) {86return reduce(scan(node, p), r);87}8889/**90* Scans a sequence of nodes.91* @param nodes the nodes to be scanned92* @param p a parameter value to be passed to the visit method for each node93* @return the combined return value from the visit methods.94* The values are combined using the {@link #reduce reduce} method.95*/96public R scan(Iterable<? extends DocTree> nodes, P p) {97R r = null;98if (nodes != null) {99boolean first = true;100for (DocTree node : nodes) {101r = (first ? scan(node, p) : scanAndReduce(node, p, r));102first = false;103}104}105return r;106}107108private R scanAndReduce(Iterable<? extends DocTree> nodes, P p, R r) {109return reduce(scan(nodes, p), r);110}111112/**113* Reduces two results into a combined result.114* The default implementation is to return the first parameter.115* The general contract of the method is that it may take any action whatsoever.116* @param r1 the first of the values to be combined117* @param r2 the second of the values to be combined118* @return the result of combining the two parameters119*/120public R reduce(R r1, R r2) {121return r1;122}123124125/* ***************************************************************************126* Visitor methods127****************************************************************************/128129/**130* {@inheritDoc} This implementation scans the children in left to right order.131*132* @param node {@inheritDoc}133* @param p {@inheritDoc}134* @return the result of scanning135*/136@Override137public R visitAttribute(AttributeTree node, P p) {138return scan(node.getValue(), p);139}140141/**142* {@inheritDoc} This implementation scans the children in left to right order.143*144* @param node {@inheritDoc}145* @param p {@inheritDoc}146* @return the result of scanning147*/148@Override149public R visitAuthor(AuthorTree node, P p) {150return scan(node.getName(), p);151}152153/**154* {@inheritDoc} This implementation returns {@code null}.155*156* @param node {@inheritDoc}157* @param p {@inheritDoc}158* @return the result of scanning159*/160@Override161public R visitComment(CommentTree node, P p) {162return null;163}164165/**166* {@inheritDoc} This implementation scans the children in left to right order.167*168* @param node {@inheritDoc}169* @param p {@inheritDoc}170* @return the result of scanning171*/172@Override173public R visitDeprecated(DeprecatedTree node, P p) {174return scan(node.getBody(), p);175}176177/**178* {@inheritDoc} This implementation scans the children in left to right order.179*180* @param node {@inheritDoc}181* @param p {@inheritDoc}182* @return the result of scanning183*/184@Override185public R visitDocComment(DocCommentTree node, P p) {186R r = scan(node.getFirstSentence(), p);187r = scanAndReduce(node.getBody(), p, r);188r = scanAndReduce(node.getBlockTags(), p, r);189return r;190}191192/**193* {@inheritDoc} This implementation returns {@code null}.194*195* @param node {@inheritDoc}196* @param p {@inheritDoc}197* @return the result of scanning198*/199@Override200public R visitDocRoot(DocRootTree node, P p) {201return null;202}203204/**205* {@inheritDoc} This implementation returns {@code null}.206*207* @param node {@inheritDoc}208* @param p {@inheritDoc}209* @return the result of scanning210*/211@Override212public R visitDocType(DocTypeTree node, P p) {213return null;214}215216/**217* {@inheritDoc} This implementation returns {@code null}.218*219* @param node {@inheritDoc}220* @param p {@inheritDoc}221* @return the result of scanning222*/223@Override224public R visitEndElement(EndElementTree node, P p) {225return null;226}227228/**229* {@inheritDoc} This implementation returns {@code null}.230*231* @param node {@inheritDoc}232* @param p {@inheritDoc}233* @return the result of scanning234*/235@Override236public R visitEntity(EntityTree node, P p) {237return null;238}239240/**241* {@inheritDoc} This implementation returns {@code null}.242*243* @param node {@inheritDoc}244* @param p {@inheritDoc}245* @return the result of scanning246*/247@Override248public R visitErroneous(ErroneousTree node, P p) {249return null;250}251252/**253* {@inheritDoc} This implementation scans the children in left to right order.254*255* @param node {@inheritDoc}256* @param p {@inheritDoc}257* @return the result of scanning258*/259@Override260public R visitHidden(HiddenTree node, P p) {261return scan(node.getBody(), p);262}263264/**265* {@inheritDoc} This implementation returns {@code null}.266*267* @param node {@inheritDoc}268* @param p {@inheritDoc}269* @return the result of scanning270*/271@Override272public R visitIdentifier(IdentifierTree node, P p) {273return null;274}275276/**277* {@inheritDoc} This implementation scans the children in left to right order.278*279* @param node {@inheritDoc}280* @param p {@inheritDoc}281* @return the result of scanning282*/283@Override284public R visitIndex(IndexTree node, P p) {285R r = scan(node.getSearchTerm(), p);286r = scanAndReduce(node.getDescription(), p, r);287return r;288}289290/**291* {@inheritDoc} This implementation returns {@code null}.292*293* @param node {@inheritDoc}294* @param p {@inheritDoc}295* @return the result of scanning296*/297@Override298public R visitInheritDoc(InheritDocTree node, P p) {299return null;300}301302/**303* {@inheritDoc} This implementation scans the children in left to right order.304*305* @param node {@inheritDoc}306* @param p {@inheritDoc}307* @return the result of scanning308*/309@Override310public R visitLink(LinkTree node, P p) {311R r = scan(node.getReference(), p);312r = scanAndReduce(node.getLabel(), p, r);313return r;314}315316/**317* {@inheritDoc} This implementation scans the children in left to right order.318*319* @param node {@inheritDoc}320* @param p {@inheritDoc}321* @return the result of scanning322*/323@Override324public R visitLiteral(LiteralTree node, P p) {325return scan(node.getBody(), p);326}327328/**329* {@inheritDoc} This implementation scans the children in left to right order.330*331* @param node {@inheritDoc}332* @param p {@inheritDoc}333* @return the result of scanning334*/335@Override336public R visitParam(ParamTree node, P p) {337R r = scan(node.getName(), p);338r = scanAndReduce(node.getDescription(), p, r);339return r;340}341342/**343* {@inheritDoc} This implementation scans the children in left to right order.344*345* @param node {@inheritDoc}346* @param p {@inheritDoc}347* @return the result of scanning348*/349@Override350public R visitProvides(ProvidesTree node, P p) {351R r = scan(node.getServiceType(), p);352r = scanAndReduce(node.getDescription(), p, r);353return r;354}355356/**357* {@inheritDoc} This implementation returns {@code null}.358*359* @param node {@inheritDoc}360* @param p {@inheritDoc}361* @return the result of scanning362*/363@Override364public R visitReference(ReferenceTree node, P p) {365return null;366}367368/**369* {@inheritDoc} This implementation scans the children in left to right order.370*371* @param node {@inheritDoc}372* @param p {@inheritDoc}373* @return the result of scanning374*/375@Override376public R visitReturn(ReturnTree node, P p) {377return scan(node.getDescription(), p);378}379380/**381* {@inheritDoc} This implementation scans the children in left to right order.382*383* @param node {@inheritDoc}384* @param p {@inheritDoc}385* @return the result of scanning386*/387@Override388public R visitSee(SeeTree node, P p) {389return scan(node.getReference(), p);390}391392/**393* {@inheritDoc} This implementation scans the children in left to right order.394*395* @param node {@inheritDoc}396* @param p {@inheritDoc}397* @return the result of scanning398*/399@Override400public R visitSerial(SerialTree node, P p) {401return scan(node.getDescription(), p);402}403404/**405* {@inheritDoc} This implementation scans the children in left to right order.406*407* @param node {@inheritDoc}408* @param p {@inheritDoc}409* @return the result of scanning410*/411@Override412public R visitSerialData(SerialDataTree node, P p) {413return scan(node.getDescription(), p);414}415416/**417* {@inheritDoc} This implementation scans the children in left to right order.418*419* @param node {@inheritDoc}420* @param p {@inheritDoc}421* @return the result of scanning422*/423@Override424public R visitSerialField(SerialFieldTree node, P p) {425R r = scan(node.getName(), p);426r = scanAndReduce(node.getType(), p, r);427r = scanAndReduce(node.getDescription(), p, r);428return r;429}430431/**432* {@inheritDoc} This implementation scans the children in left to right order.433*434* @param node {@inheritDoc}435* @param p {@inheritDoc}436* @return the result of scanning437*/438@Override439public R visitSince(SinceTree node, P p) {440return scan(node.getBody(), p);441}442443/**444* {@inheritDoc} This implementation scans the children in left to right order.445*446* @param node {@inheritDoc}447* @param p {@inheritDoc}448* @return the result of scanning449*/450@Override451public R visitStartElement(StartElementTree node, P p) {452return scan(node.getAttributes(), p);453}454455/**456* {@inheritDoc} This implementation scans the children in left to right order.457*458* @param node {@inheritDoc}459* @param p {@inheritDoc}460* @return the result of scanning461* @since 10462*/463@Override464public R visitSummary(SummaryTree node, P p) {465return scan(node.getSummary(), p);466}467468/**469* {@inheritDoc} This implementation returns {@code null}.470*471* @param node {@inheritDoc}472* @param p {@inheritDoc}473* @return the result of scanning474* @since 12475*/476@Override477public R visitSystemProperty(SystemPropertyTree node, P p) {478return null;479}480481/**482* {@inheritDoc} This implementation returns {@code null}.483*484* @param node {@inheritDoc}485* @param p {@inheritDoc}486* @return the result of scanning487*/488@Override489public R visitText(TextTree node, P p) {490return null;491}492493/**494* {@inheritDoc} This implementation scans the children in left to right order.495*496* @param node {@inheritDoc}497* @param p {@inheritDoc}498* @return the result of scanning499*/500@Override501public R visitThrows(ThrowsTree node, P p) {502R r = scan(node.getExceptionName(), p);503r = scanAndReduce(node.getDescription(), p, r);504return r;505}506507/**508* {@inheritDoc} This implementation scans the children in left to right order.509*510* @param node {@inheritDoc}511* @param p {@inheritDoc}512* @return the result of scanning513*/514@Override515public R visitUnknownBlockTag(UnknownBlockTagTree node, P p) {516return scan(node.getContent(), p);517}518519/**520* {@inheritDoc} This implementation scans the children in left to right order.521*522* @param node {@inheritDoc}523* @param p {@inheritDoc}524* @return the result of scanning525*/526@Override527public R visitUnknownInlineTag(UnknownInlineTagTree node, P p) {528return scan(node.getContent(), p);529}530531/**532* {@inheritDoc} This implementation scans the children in left to right order.533*534* @param node {@inheritDoc}535* @param p {@inheritDoc}536* @return the result of scanning537*/538@Override539public R visitUses(UsesTree node, P p) {540R r = scan(node.getServiceType(), p);541r = scanAndReduce(node.getDescription(), p, r);542return r;543}544545/**546* {@inheritDoc} This implementation scans the children in left to right order.547*548* @param node {@inheritDoc}549* @param p {@inheritDoc}550* @return the result of scanning551*/552@Override553public R visitValue(ValueTree node, P p) {554return scan(node.getReference(), p);555}556557/**558* {@inheritDoc} This implementation scans the children in left to right order.559*560* @param node {@inheritDoc}561* @param p {@inheritDoc}562* @return the result of scanning563*/564@Override565public R visitVersion(VersionTree node, P p) {566return scan(node.getBody(), p);567}568569/**570* {@inheritDoc} This implementation returns {@code null}.571*572* @param node {@inheritDoc}573* @param p {@inheritDoc}574* @return the result of scanning575*/576@Override577public R visitOther(DocTree node, P p) {578return null;579}580581}582583584